Commit 40a330db authored by Evgeny Belyaev's avatar Evgeny Belyaev

Добавлена первая версия ЛР по сжатию изображений при помощи нейронных сетей.

Версия сделана для учебных целей.
parent 3ca1acce
#This code is the simplest example of image compression based on neural networks
#Comparison with JPEG is provided as well
#It is a demonstation for Information Theory course
#Written by Evgeny Belyaev, February 2024.
import os
import math
import numpy
from matplotlib import pyplot as plt
from PIL import Image
import imghdr
import tensorflow
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Model
from keras import backend as K
#import C-implementation of Witten&Neal&Cleary-1987 arithmetic coding as a external module
from EntropyCodec import *
#source folder with test images
testfolder = './test/'
#source folder with train images
trainfolder = './train/'
#size of test and train images
w=128
h=128
#If 0, then the training will be started, otherwise the model will be readed from a file
LoadModel = 1
#Training parameters
batch_size = 10
#Number of bits for representation of the layers sample in the training process
bt = 3
epochs = 3000
#epochs = 100
#Model parameters
n1=128
n2=32
n3=16
#Number of images to be compressed and shown from the test folder
NumImagesToShow = 5
#Number of bits for representation of the layers sample
b = 3
#Compute PSNR in RGB domain
def PSNR_RGB(image1,image2):
width, height = image1.size
I1 = numpy.array(image1.getdata()).reshape(image1.size[0], image1.size[1], 3)
I2 = numpy.array(image2.getdata()).reshape(image2.size[0], image2.size[1], 3)
I1 = numpy.reshape(I1, width * height * 3)
I2 = numpy.reshape(I2, width * height * 3)
I1 = I1.astype(float)
I2 = I2.astype(float)
mse = numpy.mean((I1 - I2) ** 2)
if (mse == 0): # MSE is zero means no noise is present in the signal .
psnr=100.0
else:
max_pixel = 255.0
psnr = 20 * math.log10(max_pixel / math.sqrt(mse))
#print("PSNR = %5.2f dB" % psnr)
return psnr
#Compute PSNR between two vectors
def PSNR(y_true, y_pred):
max_pixel = 1.0
return 10.0 * (1.0 / math.log(10)) * K.log((max_pixel ** 2) / (K.mean(K.square(y_pred - y_true))))
#reads all images from folder and puts them into x array
def LoadImagesFromFolder (foldername):
dir_list = os.listdir(foldername)
N = 0
Nmax = 0
for name in dir_list:
fullname = foldername + name
filetype = imghdr.what(fullname)
if filetype is None:
print('')
else:
Nmax = Nmax + 1
x = numpy.zeros([Nmax, w, h, 3])
N = 0
for name in dir_list:
fullname = foldername + name
filetype = imghdr.what(fullname)
if filetype is None:
print('Unknown image format for file: ', name)
else:
print('Progress: N = %i' % N)
image = Image.open(fullname)
I1 = numpy.array(image.getdata()).reshape(image.size[0], image.size[1], 3)
x[N, :, :, :] = I1
N = N + 1
return x
#Model training function
def ImageCodecModel(trainfolder):
input = layers.Input(shape=(w, h, 3))
# Encoder
e1 = layers.Conv2D(n1, (7, 7), activation="relu", padding="same")(input)
e1 = layers.MaxPooling2D((2, 2), padding="same")(e1)
e2 = layers.Conv2D(n2, (5, 5), activation="relu", padding="same")(e1)
e2 = layers.MaxPooling2D((2, 2), padding="same")(e2)
e3 = layers.Conv2D(n3, (3, 3), activation="relu", padding="same")(e2)
e3 = layers.MaxPooling2D((2, 2), padding="same")(e3)
#add noise during training (needed for layer quantinzation)
e3 = e3 + tensorflow.random.uniform(tensorflow.shape(e3), 0, tensorflow.math.reduce_max(e3)/pow(2, bt+1))
# Decoder
x = layers.Conv2DTranspose(n3, (3, 3), strides=2, activation="relu", padding="same")(e3)
x = layers.Conv2DTranspose(n2, (5, 5), strides=2, activation="relu", padding="same")(x)
x = layers.Conv2DTranspose(n1, (7, 7), strides=2, activation="relu", padding="same")(x)
x = layers.Conv2D(3, (3, 3), activation="sigmoid", padding="same")(x)
# Autoencoder
encoder = Model(input, e3)
decoder = Model(e3, x)
autoencoder = Model(input, x)
autoencoder.compile(optimizer="adam", loss='mean_squared_error')
autoencoder.summary()
if LoadModel == 0:
xtrain = LoadImagesFromFolder(trainfolder)
xtrain = xtrain / 255
autoencoder.fit(xtrain, xtrain, epochs=epochs, batch_size=batch_size,shuffle=True)
autoencoder.save('autoencodertemp.mdl')
encoder.save('encoder.mdl')
decoder.save('decoder.mdl')
else:
autoencoder = keras.models.load_model('autoencodertemp.mdl')
encoder = keras.models.load_model('encoder.mdl')
decoder = keras.models.load_model('decoder.mdl')
return encoder,decoder
#Compresses input layer by multi-alphabet arithmetic coding using memoryless source model
def EntropyEncoder (filename,enclayers,size_z,size_h,size_w):
temp = numpy.zeros((size_z, size_h, size_w), numpy.uint8, 'C')
for z in range(size_z):
for h in range(size_h):
for w in range(size_w):
temp[z][h][w] = enclayers[z][h][w]
maxbinsize = (size_h * size_w * size_z)
bitstream = numpy.zeros(maxbinsize, numpy.uint8, 'C')
StreamSize = numpy.zeros(1, numpy.int32, 'C')
HiddenLayersEncoder(temp, size_w, size_h, size_z, bitstream, StreamSize)
name = filename
path = './'
fp = open(os.path.join(path, name), 'wb')
out = bitstream[0:StreamSize[0]]
out.astype('uint8').tofile(fp)
fp.close()
#Decompresses input layer by multi-alphabet arithmetic coding using memoryless source model
def EntropyDecoder (filename,size_z,size_h,size_w):
fp = open(filename, 'rb')
bitstream = fp.read()
fp.close()
bitstream = numpy.frombuffer(bitstream, dtype=numpy.uint8)
declayers = numpy.zeros((size_z, size_h, size_w), numpy.uint8, 'C')
FrameOffset = numpy.zeros(1, numpy.int32, 'C')
FrameOffset[0] = 0
HiddenLayersDecoder(declayers, size_w, size_h, size_z, bitstream, FrameOffset)
return declayers
#This function is searching for the JPEG quality factor (QF)
#which provides neares compression to TargetBPP
def JPEGRDSingleImage(X,TargetBPP,i):
X = X*255
image = Image.fromarray(X.astype('uint8'), 'RGB')
width, height = image. size
realbpp = 0
realpsnr = 0
realQ = 0
for Q in range(101):
image.save('test.jpeg', "JPEG", quality=Q)
image_dec = Image.open('test.jpeg')
bytesize = os.path.getsize('test.jpeg')
bpp = bytesize*8/(width*height)
psnr = PSNR_RGB(image, image_dec)
if abs(realbpp-TargetBPP)>abs(bpp-TargetBPP):
realbpp=bpp
realpsnr=psnr
realQ = Q
JPEGfilename = 'image%i.jpeg' % i
image.save(JPEGfilename, "JPEG", quality=realQ)
return realQ, realbpp, realpsnr
# Main function
if __name__ == '__main__':
#Load test images
xtest = LoadImagesFromFolder(testfolder)
xtest = xtest / 255
#Train the model
encoder, decoder = ImageCodecModel(trainfolder)
#Run the model for first NumImagesToShow images from the test set
encoded_layers = encoder.predict(xtest, batch_size=NumImagesToShow)
max_encoded_layers = numpy.zeros(NumImagesToShow, numpy.float16, 'C')
#normalization the layer to interval [0,1)
for i in range(NumImagesToShow):
max_encoded_layers[i] = numpy.max(encoded_layers[i])
encoded_layers[i] = encoded_layers[i] / max_encoded_layers[i]
#Quantization of layer to b bits
encoded_layers1 = numpy.clip(encoded_layers, 0, 0.9999999)
encoded_layers1 = K.cast(encoded_layers1*pow(2, b), "int32")
#Encoding and decoding of each quantized layer by arithmetic coding
bpp = numpy.zeros(NumImagesToShow, numpy.float16, 'C')
declayers = numpy.zeros((NumImagesToShow,16, 16, 16), numpy.uint8, 'C')
for i in range(NumImagesToShow):
binfilename = 'image%i.bin' % i
EntropyEncoder(binfilename, encoded_layers1[i], 16, 16, 16)
bytesize = os.path.getsize(binfilename)
bpp[i] = bytesize * 8 / (w * h)
declayers[i] = EntropyDecoder(binfilename, 16, 16, 16)
#Dequantization and denormalization of each layer
print(bpp)
shift = 1.0/pow(2, b+1)
declayers = K.cast(declayers, "float32") / pow(2, b)
declayers = declayers + shift
encoded_layers_quantized = numpy.zeros((NumImagesToShow, 16, 16, 16), numpy.double, 'C')
for i in range(NumImagesToShow):
encoded_layers_quantized[i] = K.cast(declayers[i]*max_encoded_layers[i], "float32")
encoded_layers[i] = K.cast(encoded_layers[i] * max_encoded_layers[i], "float32")
decoded_imgs = decoder.predict(encoded_layers, batch_size=NumImagesToShow)
decoded_imgsQ = decoder.predict(encoded_layers_quantized, batch_size=NumImagesToShow)
#Shows NumImagesToShow images from the test set
#For each image the following results are presented
#Original image
#Image, represented by the model (without quantization)
#Image, represented by the model with quantization and compression of the layers samples
#Corresponding JPEG image at the same compression level
for i in range(NumImagesToShow):
title = ''
plt.subplot(4, NumImagesToShow, i + 1).set_title(title, fontsize=10)
plt.imshow(xtest[i, :, :, :], interpolation='nearest')
plt.axis(False)
for i in range(NumImagesToShow):
psnr = PSNR(xtest[i, :, :, :], decoded_imgs[i, :, :, :])
title = '%2.2f' % psnr
plt.subplot(4, NumImagesToShow, NumImagesToShow + i + 1).set_title(title, fontsize=10)
plt.imshow(decoded_imgs[i, :, :, :], interpolation='nearest')
plt.axis(False)
for i in range(NumImagesToShow):
psnr = PSNR(xtest[i, :, :, :], decoded_imgsQ[i, :, :, :])
title = '%2.2f %2.2f' % (psnr, bpp[i])
plt.subplot(4, NumImagesToShow, 2*NumImagesToShow + i + 1).set_title(title, fontsize=10)
plt.imshow(decoded_imgsQ[i, :, :, :], interpolation='nearest')
plt.axis(False)
for i in range(NumImagesToShow):
JPEGQP,JPEGrealbpp, JPEGrealpsnr = JPEGRDSingleImage(xtest[i, :, :, :], bpp[i],i)
JPEGfilename = 'image%i.jpeg' % i
JPEGimage = Image.open(JPEGfilename)
title = '%2.2f %2.2f' % (JPEGrealpsnr,JPEGrealbpp)
plt.subplot(4, NumImagesToShow, 3*NumImagesToShow + i + 1).set_title(title, fontsize=10)
plt.imshow(JPEGimage, interpolation='nearest')
plt.axis(False)
plt.show()
\ No newline at end of file
del EntropyCodec.cp39-win_amd64.pyd
del ..\EntropyCodec.cp39-win_amd64.pyd
python.exe EntropySetup.py build_ext --inplace
pause
\ No newline at end of file
from setuptools import setup, Extension
import os
import pybind11
functions_module = Extension(
name='EntropyCodec',
sources=['wrapper.cpp'],
include_dirs=[os.path.join(os.getenv('PYTHON_DIR'), 'include'),
os.path.join(pybind11.__path__[0], 'include')]
)
setup(ext_modules=[functions_module], options={"build_ext": {"build_lib": ".."}})
// ImageCodec.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include "mcoder.h"
int BitPlaneEncoder(unsigned char *obuffer, unsigned char *layer1, int w1, int h1, int z1, int *bitsize)
{
BiContextType bin_ctx;
int code_len = 0;
EncodingEnvironmentPtr eep;
unsigned char *bufptr = obuffer;
eep = arienco_create_encoding_environment();
arienco_start_encoding(eep, bufptr, &code_len);
biari_init_context(&bin_ctx, "ctx");
for (int z = 0;z < z1;z++)
{
for (int i = 0;i < h1;i++)
{
for (int j = 0;j < w1;j++)
{
biari_encode_symbol(eep, layer1[z*h1*w1+i*w1+j], &bin_ctx);
}
}
}
biari_encode_symbol(eep, 0, &bin_ctx);
biari_encode_symbol(eep, 1, &bin_ctx);
biari_encode_symbol(eep, 0, &bin_ctx);
biari_encode_symbol(eep, 1, &bin_ctx);
arienco_done_encoding(eep);
arienco_delete_encoding_environment(eep);
*bitsize = code_len / 8;
return code_len / 8;
}
int BitPlaneDecoder(unsigned char *obuffer, unsigned char *layer1, int w1, int h1, int z1, int *offset)
{
BiContextType bin_ctx;
int code_len = 0;
DecodingEnvironmentPtr dep;
unsigned char *bufptr = obuffer;
bufptr += (*offset);
dep = arideco_create_decoding_environment();
arideco_start_decoding(dep, bufptr, 0, &code_len);
biari_init_context(&bin_ctx, "ctx");
for (int z = 0;z < z1;z++)
{
for (int i = 0;i < h1;i++)
{
for (int j = 0;j < w1;j++)
{
layer1[z*h1*w1 + i * w1 + j] = biari_decode_symbol(dep, &bin_ctx);
}
}
}
*offset = code_len;
arideco_delete_decoding_environment(dep);
return 0;
}
int main(int argc, char* argv[])
{
return 0;
}
\ No newline at end of file
#include <stdlib.h>
#include <stdio.h>
#include "mcoder.h"
#include <math.h>
/*!
************************************************************************
* \brief
* Allocates memory for the DecodingEnvironment struct
* \return DecodingContextPtr
* allocates memory
************************************************************************
*/
DecodingEnvironmentPtr arideco_create_decoding_environment()
{
DecodingEnvironmentPtr dep;
if ((dep = (DecodingEnvironmentPtr)calloc(1,sizeof(DecodingEnvironment))) == NULL)
printf("arideco_create_decoding_environment: dep");
return dep;
}
/*!
***********************************************************************
* \brief
* Frees memory of the DecodingEnvironment struct
***********************************************************************
*/
void arideco_delete_decoding_environment(DecodingEnvironmentPtr dep)
{
free(dep);
}
/*!
************************************************************************
* \brief
* Initializes the DecodingEnvironment for the arithmetic coder
************************************************************************
*/
void arideco_start_decoding(DecodingEnvironmentPtr dep, unsigned char *cpixcode,
int firstbyte, int *cpixcode_len )
{
register unsigned int bbit = 0;
int value = 0;
dep->Dcodestrm = cpixcode;
dep->Dcodestrm_len = (unsigned int*)cpixcode_len;
dep->Dvalue = 0;
for (int i = 1; i <= BITS_IN_REGISTER; i++)
{
Get1Bit(dep->Dcodestrm, *dep->Dcodestrm_len, bbit);
dep->Dvalue = 2 * dep->Dvalue + bbit;
}
dep->Dlow = 0;
dep->Drange = HALF-2;
}
unsigned int biari_decode_symbol(DecodingEnvironmentPtr dep, BiContextTypePtr bi_ct)
{
int bbit;
register unsigned int low = dep->Dlow;
register unsigned int value = dep->Dvalue;
register unsigned int range = dep->Drange;
unsigned int symbol;
unsigned int cum = (int)((((long) (value - low) + 1) * bi_ct->freq_all - 1) / range);
for (int i=0;i<ALPHABET_SIZE;i++)
{
if (bi_ct->cum_freq [i] > cum)
{
break;
}
symbol = i;
}
low = low + (range * bi_ct->cum_freq [symbol]) / bi_ct->freq_all;
range = (range*bi_ct->freq [symbol])/bi_ct->freq_all;
range = max(1,range);
bi_ct->freq[symbol]++;
bi_ct->freq_all++;
if (bi_ct->freq_all>16384)
{
bi_ct->freq_all=0;
for (int i=0;i<ALPHABET_SIZE;i++)
{
bi_ct->freq[i]=max(1,bi_ct->freq[i]>>1);
bi_ct->freq_all+=bi_ct->freq[i];
}
}
bi_ct->cum_freq[0]=0;
for (int i=1;i<=ALPHABET_SIZE;i++)
{
bi_ct->cum_freq[i] = bi_ct->cum_freq[i-1]+bi_ct->freq[i-1];
}
while (range < QUARTER)
{
if (low >= HALF)
{
low -= HALF;
value -= HALF;
}
else
if (low < QUARTER)
{
}
else
{
low -= QUARTER;
value -= QUARTER;
}
// Double range
range <<= 1;
low <<= 1;
Get1Bit(dep->Dcodestrm, *dep->Dcodestrm_len, bbit);
value = (value << 1) | bbit;
}
dep->Drange = range;
dep->Dvalue = value;
dep->Dlow = low;
return(symbol);
}
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "mcoder.h"
/*!
************************************************************************
* \brief
* Initializes a given context with some pre-defined probability state
************************************************************************
*/
void biari_init_context
(
BiContextTypePtr ctx,
char* name
)
{
ctx->freq_all = 0;
for (int i=0;i<ALPHABET_SIZE;i++)
{
ctx->freq[i] = 1;
ctx->freq_all+=ctx->freq[i];
}
ctx->cum_freq[0]=0;
for (int i=1;i<=ALPHABET_SIZE;i++)
{
ctx->cum_freq[i] = ctx->cum_freq[i-1]+ctx->freq[i-1];
}
}
/*!
************************************************************************
* \brief
* Allocates memory for the EncodingEnvironment struct
************************************************************************
*/
EncodingEnvironmentPtr arienco_create_encoding_environment()
{
EncodingEnvironmentPtr eep;
if ( (eep = (EncodingEnvironmentPtr) calloc(1,sizeof(EncodingEnvironment))) == NULL)
printf("arienco_create_encoding_environment: eep");
return eep;
}
/*!
************************************************************************
* \brief
* Frees memory of the EncodingEnvironment struct
************************************************************************
*/
void arienco_delete_encoding_environment(EncodingEnvironmentPtr eep)
{
if (eep != NULL)
{
free(eep);
}
}
/*!
************************************************************************
* \brief
* Initializes the EncodingEnvironment for the arithmetic coder
************************************************************************
*/
void arienco_start_encoding(EncodingEnvironmentPtr eep,
unsigned char *code_buffer,
int *code_len )
{
eep->Elow = 0;
eep->Erange = HALF-2;
eep->Ebits_to_follow = 0;
eep->Ecodestrm = code_buffer;
eep->Ecodestrm_len = (unsigned int*)code_len;
}
/*!
************************************************************************
* \brief
* Terminates the arithmetic codeword, writes stop bit and stuffing bytes (if any)
************************************************************************
*/
void arienco_done_encoding(EncodingEnvironmentPtr eep)
{
if((eep->Elow >> (BITS_IN_REGISTER-1)) & 1)
{
put_one_bit_1_plus_outstanding;
}
else
{
put_one_bit_0_plus_outstanding;
}
Put1Bit(eep->Ecodestrm, *eep->Ecodestrm_len, (eep->Elow >> (BITS_IN_REGISTER-2))&1);
Put1Bit(eep->Ecodestrm, *eep->Ecodestrm_len, 1);
*eep->Ecodestrm_len = (*eep->Ecodestrm_len+7) & ~7;
}
void biari_encode_symbol(EncodingEnvironmentPtr eep, signed int symbol, BiContextTypePtr bi_ct)
{
register unsigned int range = eep->Erange;
register unsigned int low = eep->Elow;
low = low + (range * bi_ct->cum_freq [symbol]) / bi_ct->freq_all;
range = (range*bi_ct->freq [symbol])/bi_ct->freq_all;
range=max(1,range);
bi_ct->freq[symbol]++;
bi_ct->freq_all++;
if (bi_ct->freq_all>16384)
{
bi_ct->freq_all=0;
for (int i=0;i<ALPHABET_SIZE;i++)
{
bi_ct->freq[i]=max(1,bi_ct->freq[i]>>1);
bi_ct->freq_all+=bi_ct->freq[i];
}
}
bi_ct->cum_freq[0]=0;
for (int i=1;i<=ALPHABET_SIZE;i++)
{
bi_ct->cum_freq[i] = bi_ct->cum_freq[i-1]+bi_ct->freq[i-1];
}
// renormalization
while (range < QUARTER)
{
if (low >= HALF)
{
put_one_bit_1_plus_outstanding;
low -= HALF;
}
else
if (low < QUARTER)
{
put_one_bit_0_plus_outstanding;
}
else
{
eep->Ebits_to_follow++;
low -= QUARTER;
}
low <<= 1;
range <<= 1;
}
eep->Erange = range;
eep->Elow = low;
bi_ct->freq_stat[symbol]++;
}
ގœ浂* ȾG(e2
\ No newline at end of file
Aroot"_tf_keras_network*A{"name": "model_1", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": false, "class_name": "Functional", "config": {"name": "model_1", "trainable": true, "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 16, 16, 16]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "input_2"}, "name": "input_2", "inbound_nodes": []}, {"class_name": "Conv2DTranspose", "config": {"name": "conv2d_transpose", "trainable": true, "dtype": "float32", "filters": 16, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null, "output_padding": null}, "name": "conv2d_transpose", "inbound_nodes": [[["input_2", 0, 0, {}]]]}, {"class_name": "Conv2DTranspose", "config": {"name": "conv2d_transpose_1", "trainable": true, "dtype": "float32", "filters": 32, "kernel_size": {"class_name": "__tuple__", "items": [5, 5]}, "strides": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null, "output_padding": null}, "name": "conv2d_transpose_1", "inbound_nodes": [[["conv2d_transpose", 0, 0, {}]]]}, {"class_name": "Conv2DTranspose", "config": {"name": "conv2d_transpose_2", "trainable": true, "dtype": "float32", "filters": 128, "kernel_size": {"class_name": "__tuple__", "items": [7, 7]}, "strides": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null, "output_padding": null}, "name": "conv2d_transpose_2", "inbound_nodes": [[["conv2d_transpose_1", 0, 0, {}]]]}, {"class_name": "Conv2D", "config": {"name": "conv2d_3", "trainable": true, "dtype": "float32", "filters": 3, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "sigmoid", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d_3", "inbound_nodes": [[["conv2d_transpose_2", 0, 0, {}]]]}], "input_layers": [["input_2", 0, 0]], "output_layers": [["conv2d_3", 0, 0]]}, "shared_object_id": 13, "input_spec": [{"class_name": "InputSpec", "config": {"dtype": null, "shape": {"class_name": "__tuple__", "items": [null, 16, 16, 16]}, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {}}}], "build_input_shape": {"class_name": "TensorShape", "items": [null, 16, 16, 16]}, "is_graph_network": true, "full_save_spec": {"class_name": "__tuple__", "items": [[{"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 16, 16, 16]}, "float32", null]}], {}]}, "save_spec": {"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 16, 16, 16]}, "float32", null]}, "keras_version": "2.15.0", "backend": "tensorflow", "model_config": {"class_name": "Functional", "config": {"name": "model_1", "trainable": true, "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 16, 16, 16]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "input_2"}, "name": "input_2", "inbound_nodes": [], "shared_object_id": 0}, {"class_name": "Conv2DTranspose", "config": {"name": "conv2d_transpose", "trainable": true, "dtype": "float32", "filters": 16, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 2}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null, "output_padding": null}, "name": "conv2d_transpose", "inbound_nodes": [[["input_2", 0, 0, {}]]], "shared_object_id": 3}, {"class_name": "Conv2DTranspose", "config": {"name": "conv2d_transpose_1", "trainable": true, "dtype": "float32", "filters": 32, "kernel_size": {"class_name": "__tuple__", "items": [5, 5]}, "strides": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 4}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 5}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null, "output_padding": null}, "name": "conv2d_transpose_1", "inbound_nodes": [[["conv2d_transpose", 0, 0, {}]]], "shared_object_id": 6}, {"class_name": "Conv2DTranspose", "config": {"name": "conv2d_transpose_2", "trainable": true, "dtype": "float32", "filters": 128, "kernel_size": {"class_name": "__tuple__", "items": [7, 7]}, "strides": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 7}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 8}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null, "output_padding": null}, "name": "conv2d_transpose_2", "inbound_nodes": [[["conv2d_transpose_1", 0, 0, {}]]], "shared_object_id": 9}, {"class_name": "Conv2D", "config": {"name": "conv2d_3", "trainable": true, "dtype": "float32", "filters": 3, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "sigmoid", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 10}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 11}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d_3", "inbound_nodes": [[["conv2d_transpose_2", 0, 0, {}]]], "shared_object_id": 12}], "input_layers": [["input_2", 0, 0]], "output_layers": [["conv2d_3", 0, 0]]}}}2
 root.layer-0"_tf_keras_input_layer*{"class_name": "InputLayer", "name": "input_2", "dtype": "float32", "sparse": false, "ragged": false, "batch_input_shape": {"class_name": "__tuple__", "items": [null, 16, 16, 16]}, "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 16, 16, 16]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "input_2"}}2
root.layer_with_weights-0"_tf_keras_layer*
{"name": "conv2d_transpose", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "Conv2DTranspose", "config": {"name": "conv2d_transpose", "trainable": true, "dtype": "float32", "filters": 16, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 2}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null, "output_padding": null}, "inbound_nodes": [[["input_2", 0, 0, {}]]], "shared_object_id": 3, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {"-1": 16}}, "shared_object_id": 15}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 16, 16, 16]}}2
root.layer_with_weights-1"_tf_keras_layer*
{"name": "conv2d_transpose_1", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "Conv2DTranspose", "config": {"name": "conv2d_transpose_1", "trainable": true, "dtype": "float32", "filters": 32, "kernel_size": {"class_name": "__tuple__", "items": [5, 5]}, "strides": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 4}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 5}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null, "output_padding": null}, "inbound_nodes": [[["conv2d_transpose", 0, 0, {}]]], "shared_object_id": 6, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {"-1": 16}}, "shared_object_id": 16}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 32, 32, 16]}}2
root.layer_with_weights-2"_tf_keras_layer*
{"name": "conv2d_transpose_2", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "Conv2DTranspose", "config": {"name": "conv2d_transpose_2", "trainable": true, "dtype": "float32", "filters": 128, "kernel_size": {"class_name": "__tuple__", "items": [7, 7]}, "strides": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 7}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 8}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null, "output_padding": null}, "inbound_nodes": [[["conv2d_transpose_1", 0, 0, {}]]], "shared_object_id": 9, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {"-1": 32}}, "shared_object_id": 17}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 64, 64, 32]}}2
root.layer_with_weights-3"_tf_keras_layer*
{"name": "conv2d_3", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "Conv2D", "config": {"name": "conv2d_3", "trainable": true, "dtype": "float32", "filters": 3, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "sigmoid", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 10}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 11}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["conv2d_transpose_2", 0, 0, {}]]], "shared_object_id": 12, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 4, "axes": {"-1": 128}}, "shared_object_id": 18}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 128, 128, 128]}}2
\ No newline at end of file
Ֆ֯i ǹL(Ͳ2
\ No newline at end of file
Xroot"_tf_keras_network*X{"name": "model", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": false, "class_name": "Functional", "config": {"name": "model", "trainable": true, "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 128, 3]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "input_1"}, "name": "input_1", "inbound_nodes": []}, {"class_name": "Conv2D", "config": {"name": "conv2d", "trainable": true, "dtype": "float32", "filters": 128, "kernel_size": {"class_name": "__tuple__", "items": [7, 7]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d", "inbound_nodes": [[["input_1", 0, 0, {}]]]}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "name": "max_pooling2d", "inbound_nodes": [[["conv2d", 0, 0, {}]]]}, {"class_name": "Conv2D", "config": {"name": "conv2d_1", "trainable": true, "dtype": "float32", "filters": 32, "kernel_size": {"class_name": "__tuple__", "items": [5, 5]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d_1", "inbound_nodes": [[["max_pooling2d", 0, 0, {}]]]}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_1", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "name": "max_pooling2d_1", "inbound_nodes": [[["conv2d_1", 0, 0, {}]]]}, {"class_name": "Conv2D", "config": {"name": "conv2d_2", "trainable": true, "dtype": "float32", "filters": 16, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d_2", "inbound_nodes": [[["max_pooling2d_1", 0, 0, {}]]]}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_2", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "name": "max_pooling2d_2", "inbound_nodes": [[["conv2d_2", 0, 0, {}]]]}, {"class_name": "TFOpLambda", "config": {"name": "tf.math.reduce_max", "trainable": true, "dtype": "float32", "function": "math.reduce_max"}, "name": "tf.math.reduce_max", "inbound_nodes": [["max_pooling2d_2", 0, 0, {}]]}, {"class_name": "TFOpLambda", "config": {"name": "tf.compat.v1.shape", "trainable": true, "dtype": "float32", "function": "compat.v1.shape"}, "name": "tf.compat.v1.shape", "inbound_nodes": [["max_pooling2d_2", 0, 0, {"name": null, "out_type": "int32"}]]}, {"class_name": "TFOpLambda", "config": {"name": "tf.math.truediv", "trainable": true, "dtype": "float32", "function": "math.truediv"}, "name": "tf.math.truediv", "inbound_nodes": [["tf.math.reduce_max", 0, 0, {"y": 16, "name": null}]]}, {"class_name": "TFOpLambda", "config": {"name": "tf.random.uniform", "trainable": true, "dtype": "float32", "function": "random.uniform"}, "name": "tf.random.uniform", "inbound_nodes": [["tf.compat.v1.shape", 0, 0, {"minval": 0, "maxval": ["tf.math.truediv", 0, 0]}]]}, {"class_name": "TFOpLambda", "config": {"name": "tf.__operators__.add", "trainable": true, "dtype": "float32", "function": "__operators__.add"}, "name": "tf.__operators__.add", "inbound_nodes": [["max_pooling2d_2", 0, 0, {"y": ["tf.random.uniform", 0, 0], "name": null}]]}], "input_layers": [["input_1", 0, 0]], "output_layers": [["tf.__operators__.add", 0, 0]]}, "shared_object_id": 18, "input_spec": [{"class_name": "InputSpec", "config": {"dtype": null, "shape": {"class_name": "__tuple__", "items": [null, 128, 128, 3]}, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {}}}], "build_input_shape": {"class_name": "TensorShape", "items": [null, 128, 128, 3]}, "is_graph_network": true, "full_save_spec": {"class_name": "__tuple__", "items": [[{"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 128, 128, 3]}, "float32", "input_1"]}], {}]}, "save_spec": {"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 128, 128, 3]}, "float32", "input_1"]}, "keras_version": "2.15.0", "backend": "tensorflow", "model_config": {"class_name": "Functional", "config": {"name": "model", "trainable": true, "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 128, 3]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "input_1"}, "name": "input_1", "inbound_nodes": [], "shared_object_id": 0}, {"class_name": "Conv2D", "config": {"name": "conv2d", "trainable": true, "dtype": "float32", "filters": 128, "kernel_size": {"class_name": "__tuple__", "items": [7, 7]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 2}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d", "inbound_nodes": [[["input_1", 0, 0, {}]]], "shared_object_id": 3}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "name": "max_pooling2d", "inbound_nodes": [[["conv2d", 0, 0, {}]]], "shared_object_id": 4}, {"class_name": "Conv2D", "config": {"name": "conv2d_1", "trainable": true, "dtype": "float32", "filters": 32, "kernel_size": {"class_name": "__tuple__", "items": [5, 5]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 5}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 6}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d_1", "inbound_nodes": [[["max_pooling2d", 0, 0, {}]]], "shared_object_id": 7}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_1", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "name": "max_pooling2d_1", "inbound_nodes": [[["conv2d_1", 0, 0, {}]]], "shared_object_id": 8}, {"class_name": "Conv2D", "config": {"name": "conv2d_2", "trainable": true, "dtype": "float32", "filters": 16, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 9}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 10}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d_2", "inbound_nodes": [[["max_pooling2d_1", 0, 0, {}]]], "shared_object_id": 11}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_2", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "name": "max_pooling2d_2", "inbound_nodes": [[["conv2d_2", 0, 0, {}]]], "shared_object_id": 12}, {"class_name": "TFOpLambda", "config": {"name": "tf.math.reduce_max", "trainable": true, "dtype": "float32", "function": "math.reduce_max"}, "name": "tf.math.reduce_max", "inbound_nodes": [["max_pooling2d_2", 0, 0, {}]], "shared_object_id": 13}, {"class_name": "TFOpLambda", "config": {"name": "tf.compat.v1.shape", "trainable": true, "dtype": "float32", "function": "compat.v1.shape"}, "name": "tf.compat.v1.shape", "inbound_nodes": [["max_pooling2d_2", 0, 0, {"name": null, "out_type": "int32"}]], "shared_object_id": 14}, {"class_name": "TFOpLambda", "config": {"name": "tf.math.truediv", "trainable": true, "dtype": "float32", "function": "math.truediv"}, "name": "tf.math.truediv", "inbound_nodes": [["tf.math.reduce_max", 0, 0, {"y": 16, "name": null}]], "shared_object_id": 15}, {"class_name": "TFOpLambda", "config": {"name": "tf.random.uniform", "trainable": true, "dtype": "float32", "function": "random.uniform"}, "name": "tf.random.uniform", "inbound_nodes": [["tf.compat.v1.shape", 0, 0, {"minval": 0, "maxval": ["tf.math.truediv", 0, 0]}]], "shared_object_id": 16}, {"class_name": "TFOpLambda", "config": {"name": "tf.__operators__.add", "trainable": true, "dtype": "float32", "function": "__operators__.add"}, "name": "tf.__operators__.add", "inbound_nodes": [["max_pooling2d_2", 0, 0, {"y": ["tf.random.uniform", 0, 0], "name": null}]], "shared_object_id": 17}], "input_layers": [["input_1", 0, 0]], "output_layers": [["tf.__operators__.add", 0, 0]]}}}2
 root.layer-0"_tf_keras_input_layer*{"class_name": "InputLayer", "name": "input_1", "dtype": "float32", "sparse": false, "ragged": false, "batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 128, 3]}, "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 128, 3]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "input_1"}}2
root.layer_with_weights-0"_tf_keras_layer* {"name": "conv2d", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "Conv2D", "config": {"name": "conv2d", "trainable": true, "dtype": "float32", "filters": 128, "kernel_size": {"class_name": "__tuple__", "items": [7, 7]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 2}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["input_1", 0, 0, {}]]], "shared_object_id": 3, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 4, "axes": {"-1": 3}}, "shared_object_id": 20}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 128, 128, 3]}}2
 root.layer-2"_tf_keras_layer*{"name": "max_pooling2d", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "inbound_nodes": [[["conv2d", 0, 0, {}]]], "shared_object_id": 4, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {}}, "shared_object_id": 21}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 128, 128, 128]}}2
root.layer_with_weights-1"_tf_keras_layer*
{"name": "conv2d_1", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "Conv2D", "config": {"name": "conv2d_1", "trainable": true, "dtype": "float32", "filters": 32, "kernel_size": {"class_name": "__tuple__", "items": [5, 5]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 5}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 6}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["max_pooling2d", 0, 0, {}]]], "shared_object_id": 7, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 4, "axes": {"-1": 128}}, "shared_object_id": 22}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 64, 64, 128]}}2
 root.layer-4"_tf_keras_layer*{"name": "max_pooling2d_1", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_1", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "inbound_nodes": [[["conv2d_1", 0, 0, {}]]], "shared_object_id": 8, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {}}, "shared_object_id": 23}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 64, 64, 32]}}2
root.layer_with_weights-2"_tf_keras_layer*
{"name": "conv2d_2", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "Conv2D", "config": {"name": "conv2d_2", "trainable": true, "dtype": "float32", "filters": 16, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 9}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 10}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["max_pooling2d_1", 0, 0, {}]]], "shared_object_id": 11, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 4, "axes": {"-1": 32}}, "shared_object_id": 24}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 32, 32, 32]}}2
 root.layer-6"_tf_keras_layer*{"name": "max_pooling2d_2", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_2", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "same", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "inbound_nodes": [[["conv2d_2", 0, 0, {}]]], "shared_object_id": 12, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {}}, "shared_object_id": 25}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 32, 32, 16]}}2
 root.layer-7"_tf_keras_layer*{"name": "tf.math.reduce_max", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": true, "preserve_input_structure_in_config": true, "autocast": false, "class_name": "TFOpLambda", "config": {"name": "tf.math.reduce_max", "trainable": true, "dtype": "float32", "function": "math.reduce_max"}, "inbound_nodes": [["max_pooling2d_2", 0, 0, {}]], "shared_object_id": 13, "build_input_shape": {"class_name": "TensorShape", "items": [null, 16, 16, 16]}}2
  root.layer-8"_tf_keras_layer*{"name": "tf.compat.v1.shape", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": true, "preserve_input_structure_in_config": true, "autocast": false, "class_name": "TFOpLambda", "config": {"name": "tf.compat.v1.shape", "trainable": true, "dtype": "float32", "function": "compat.v1.shape"}, "inbound_nodes": [["max_pooling2d_2", 0, 0, {"name": null, "out_type": "int32"}]], "shared_object_id": 14, "build_input_shape": {"class_name": "TensorShape", "items": [null, 16, 16, 16]}}2

 root.layer-9"_tf_keras_layer*{"name": "tf.math.truediv", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": true, "preserve_input_structure_in_config": true, "autocast": false, "class_name": "TFOpLambda", "config": {"name": "tf.math.truediv", "trainable": true, "dtype": "float32", "function": "math.truediv"}, "inbound_nodes": [["tf.math.reduce_max", 0, 0, {"y": 16, "name": null}]], "shared_object_id": 15, "build_input_shape": {"class_name": "TensorShape", "items": []}}2
  root.layer-10"_tf_keras_layer*{"name": "tf.random.uniform", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": true, "preserve_input_structure_in_config": true, "autocast": false, "class_name": "TFOpLambda", "config": {"name": "tf.random.uniform", "trainable": true, "dtype": "float32", "function": "random.uniform"}, "inbound_nodes": [["tf.compat.v1.shape", 0, 0, {"minval": 0, "maxval": ["tf.math.truediv", 0, 0]}]], "shared_object_id": 16, "build_input_shape": {"class_name": "TensorShape", "items": [4]}}2
  root.layer-11"_tf_keras_layer*{"name": "tf.__operators__.add", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": true, "preserve_input_structure_in_config": true, "autocast": false, "class_name": "TFOpLambda", "config": {"name": "tf.__operators__.add", "trainable": true, "dtype": "float32", "function": "__operators__.add"}, "inbound_nodes": [["max_pooling2d_2", 0, 0, {"y": ["tf.random.uniform", 0, 0], "name": null}]], "shared_object_id": 17, "build_input_shape": {"class_name": "TensorShape", "items": [null, 16, 16, 16]}}2
\ No newline at end of file
#ifndef MCODER_H
#define MCODER_H
#include "stream.h"
#include <stdio.h>
//new parameters
#define BITS_IN_REGISTER 16
#define TOP_VALUE (((long) 1 << BITS_IN_REGISTER) - 1)
#define QUARTER (TOP_VALUE / 4 + 1)
#define FIRST_QTR (TOP_VALUE / 4 + 1)
#define HALF (2 * FIRST_QTR)
#define THIRD_QTR (3 * FIRST_QTR)
#define ALPHABET_SIZE 256
#define max(a,b) (((a) > (b)) ? (a) : (b))
typedef struct
{
unsigned long freq[ALPHABET_SIZE+1];
unsigned long freq_all;
unsigned long cum_freq[ALPHABET_SIZE+1];
unsigned long freq_stat[ALPHABET_SIZE+1];
} BiContextType;
typedef BiContextType *BiContextTypePtr;
#define putLogToFile(fname,...) { \
FILE *fp = fopen(fname,"at"); \
fprintf(fp,__VA_ARGS__); \
fclose(fp); \
}
#define SIGN_TO_ENCODE(x) ((x) >= 0 ? 0 : 1)
#define CABAC_ABS(x) ((x) > 0 ? (x) : -(x))
#define MAX_BITS_IN_SERIE 25
/// 25 MAXIMUM
#define PutZeros(nbits) {\
unsigned int iii;\
for(iii = 0; iii<(nbits); iii++ )\
{\
Put1Bit(eep->Ecodestrm, *eep->Ecodestrm_len, 0);\
}\
}
#define put_one_bit_1_plus_outstanding { \
Put1Bit(eep->Ecodestrm, *eep->Ecodestrm_len, 1); \
PutZeros(eep->Ebits_to_follow);\
eep->Ebits_to_follow = 0;\
}
#define PutLongOnes(nbits) {\
unsigned int i1=0xFFFFFFFF;\
int bits1;\
int main = (nbits)/MAX_BITS_IN_SERIE;\
int tail = (nbits)%MAX_BITS_IN_SERIE;\
for(bits1 = 0; bits1<main; bits1++ ) {\
PutBits(eep->Ecodestrm, *eep->Ecodestrm_len,i1,MAX_BITS_IN_SERIE);\
}\
PutBits(eep->Ecodestrm, *eep->Ecodestrm_len,i1,tail);\
}
#define put_one_bit_0_plus_outstanding { \
Put1Bit(eep->Ecodestrm, *eep->Ecodestrm_len, 0); \
if( eep->Ebits_to_follow > MAX_BITS_IN_SERIE ) \
{ \
PutLongOnes(eep->Ebits_to_follow);\
}\
else \
{\
PutBitsOnes(eep->Ecodestrm, *eep->Ecodestrm_len, eep->Ebits_to_follow);\
}\
eep->Ebits_to_follow = 0;\
}
//! struct to characterize the state of the arithmetic coding engine
typedef struct
{
unsigned int Elow, Erange, Ehigh;
unsigned int Ebits_to_follow;
unsigned char *Ecodestrm;
unsigned int *Ecodestrm_len;
} EncodingEnvironment;
typedef EncodingEnvironment *EncodingEnvironmentPtr;
// cabac_enc.c
void biari_init_context
(
BiContextTypePtr ctx,
char* name
);
EncodingEnvironmentPtr arienco_create_encoding_environment();
void arienco_delete_encoding_environment(EncodingEnvironmentPtr eep);
void arienco_start_encoding(EncodingEnvironmentPtr eep,
unsigned char *code_buffer,
int *code_len );
void arienco_done_encoding(EncodingEnvironmentPtr eep);
void biari_encode_symbol(EncodingEnvironmentPtr eep, int symbol, BiContextTypePtr bi_ct);
//! struct to characterize the state of the arithmetic coding engine
typedef struct
{
unsigned int Dlow, Drange, Dhigh;
unsigned int Dvalue;
unsigned int Dbuffer;
int Dbits_to_go;
unsigned char *Dcodestrm;
unsigned int *Dcodestrm_len;
} DecodingEnvironment;
typedef DecodingEnvironment *DecodingEnvironmentPtr;
// cabac_dec.c
DecodingEnvironmentPtr arideco_create_decoding_environment();
void arideco_delete_decoding_environment(DecodingEnvironmentPtr dep);
void arideco_start_decoding(DecodingEnvironmentPtr dep, unsigned char *cpixcode,
int firstbyte, int *cpixcode_len );
int arideco_bits_read(DecodingEnvironmentPtr dep);
void arideco_done_decoding(DecodingEnvironmentPtr dep);
unsigned int biari_decode_symbol(DecodingEnvironmentPtr dep, BiContextTypePtr bi_ct);
#endif // !MCODER_H
\ No newline at end of file
#ifndef _STREAM_H
#define _STREAM_H
// ****************************************************
// * Bits Order (w/o swap): *
// * the 1st bit in a bitstream is 0th bit (not 7th) *
// ****************************************************
#define mask(y,nb) ((unsigned int)((int)(y) & ((1L<<(nb)) - 1)))
#ifdef TMS
#define UINT32P(x) _mem4(x)
#else
#define UINT32P(x) (*((unsigned int*)(x)))
#endif
#define UINT32(x) ((unsigned int)(x))
#define UCHAR(x) ((unsigned char)(x))
#define UCHARP(x) ((unsigned char*)(x))
//-----------------------------------------------
#define PutBitsAC(stream, bitptr, x, nbits) \
{ \
UINT32P(&(UCHARP(stream)[(bitptr)>>3])) |= \
UINT32(x) << ((bitptr)&0x7); \
bitptr += nbits; \
} \
//-----------------------------------------------
//-------------------------------------------------------------------
#define Put1BitAC(stream, bitptr, x) \
{ \
if(x) UCHARP(stream)[(bitptr)>>3] |= UCHAR(1L<<((bitptr)&0x7)); \
(bitptr)++; \
} \
//-------------------------------------------------------------------
//---------------------------------------------------
#define PutBits(stream, bitptr, x, nbits) \
{ \
UINT32P(&(UCHARP(stream)[((bitptr)+7)>>3])) = 0; \
UINT32P(&(UCHARP(stream)[(bitptr)>>3])) |= \
UINT32(mask(x,nbits) << ((bitptr)&0x7)); \
bitptr += nbits; \
} \
//---------------------------------------------------
//---------------------------------------------------
#define PutBitsOnes(stream, bitptr, nbits) \
{ \
UINT32P(&(UCHARP(stream)[((bitptr)+7)>>3])) = 0; \
UINT32P(&(UCHARP(stream)[(bitptr)>>3])) |= \
UINT32(mask(0xFFFFFFFF,nbits) << ((bitptr)&0x7)); \
bitptr += nbits; \
} \
//---------------------------------------------------
//---------------------------------------------------
#define PutBitsZeros(stream, bitptr, nbits) \
{ \
UINT32P(&(UCHARP(stream)[((bitptr)+7)>>3])) = 0; \
bitptr += nbits; \
} \
//---------------------------------------------------
//------------------------------------------------------------------
#define ShiftBitPtr(bitptr, nbits) bitptr += nbits;
//------------------------------------------------------------------
// *********************************************
// * Put a bit into the bitstream. *
// * x can be any value; *
// * only if x~=0, the current bit is set to 1 *
// *********************************************
//---------------------------------------------------------------
#define Put1Bit(stream, bitptr, x) \
{ \
UINT32P(&(UCHARP(stream)[((bitptr)+7)>>3]) ) = 0; \
if((x)!=0) UINT32P(&(UCHARP(stream)[(bitptr)>>3])) |= \
UINT32(1L << ((bitptr)&0x7)); \
(bitptr)++; \
} \
//---------------------------------------------------------------
//-------------------------------------------------------
#define Put1BitOne(stream, bitptr) \
{ \
UINT32P(&(UCHARP(stream)[((bitptr)+7)>>3]) ) = 0; \
UINT32P(&(UCHARP(stream)[(bitptr)>>3]) ) |= \
UINT32(1L << ((bitptr)&0x7)); \
(bitptr)++; \
} \
//-------------------------------------------------------
//-------------------------------------------------------
#define Put1BitZero(stream, bitptr) \
{ \
UINT32P(&(UCHARP(stream)[((bitptr)+7)>>3]) ) = 0; \
(bitptr)++; \
} \
//-------------------------------------------------------
//-------------------------------------------------------
#define Get1BitCABAC(stream, bitptr, x) \
{ \
x = (stream)[(bitptr)>>3]; \
x >>= (bitptr) & 0x7 ; \
x &= 1; \
(bitptr)++; \
}
//-------------------------------------------------------
#define GetBits(stream, bitptr, x, nbits) \
{ \
x = UINT32P(&(UCHARP(stream)[(bitptr)>>3])); \
x >>= (bitptr) & 0x7 ; \
bitptr += nbits; \
} \
//-------------------------------------------------------
//-------------------------------------------------------
#define Get1Bit(stream, bitptr, x) \
{ \
x = UINT32P(&(UCHARP(stream)[(bitptr)>>3])); \
x >>= (bitptr) & 0x7 ; \
x &= 1; \
(bitptr)++; \
} \
//-------------------------------------------------------
#define Get1BitCABAC(stream, bitptr, x) \
{ \
x = (stream)[(bitptr)>>3]; \
x >>= (bitptr) & 0x7 ; \
x &= 1; \
(bitptr)++; \
}
#endif // _STREAM_H
test/1.png

41.7 KB

test/11.png

45.5 KB

test/12.png

47.3 KB

test/13.png

38.6 KB

test/14.png

41.4 KB

test/15.png

43.7 KB

test/16.png

43.5 KB

test/17.png

44.7 KB

test/18.png

46.4 KB

test/19.png

42.3 KB

test/2.png

40.1 KB

test/20.png

40.3 KB

test/21.png

46.5 KB

test/5.png

48.4 KB

test/6.png

40.3 KB

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/numpy.h>
#include "ImageCoder.cpp"
#include "ac_enc.cpp"
#include "ac_dec.cpp"
namespace py = pybind11;
template<typename T>
T*** from_py_array2(py::array_t<T>& py_array)
{
return (T***)py_array.data();
}
template<typename T>
T* from_py_array(py::array_t<T>& py_array)
{
return (T*)py_array.data();
}
PYBIND11_MODULE(EntropyCodec, m){
m.def("HiddenLayersEncoder", [](py::array_t<unsigned char>& layer1, int w1, int h1, int z1,
py::array_t<unsigned char>& stream, py::array_t<int>& bitsize)
{
auto l1 = from_py_array(layer1);
auto st = from_py_array(stream);
auto bs = from_py_array(bitsize);
BitPlaneEncoder(st, l1, w1, h1, z1, bs);
});
m.def("HiddenLayersDecoder", [](py::array_t<unsigned char>& layer1, int w1, int h1, int z1,
py::array_t<unsigned char>& stream, py::array_t<int>& offset)
{
auto l1 = from_py_array(layer1);
auto st = from_py_array(stream);
auto of = from_py_array(offset);
BitPlaneDecoder(st, l1, w1, h1, z1, of);
});
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment