Resource exhausted Error: Keras using Tensorflow backend - memory

I created a docker image with Tensorflow and Keras and when I create a container it works fine but only for the first time. The second time when I try to run the same code it gives me an error:
2017-10-04 13:57:25.359384: I tensorflow/core/common_runtime/bfc_allocator.cc:660] Bin for 1.12MiB was 1.00MiB, Chunk State:
2017-10-04 13:57:25.359402: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac00000 of size 1280
2017-10-04 13:57:25.359420: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac00500 of size 256
2017-10-04 13:57:25.359435: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac00600 of size 256
2017-10-04 13:57:25.359463: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac00700 of size 256
2017-10-04 13:57:25.359478: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac00800 of size 256
2017-10-04 13:57:25.359492: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac00900 of size 512
2017-10-04 13:57:25.359507: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac00b00 of size 256
2017-10-04 13:57:25.359521: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac00c00 of size 256
2017-10-04 13:57:25.359538: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac00d00 of size 1024
2017-10-04 13:57:25.359551: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac01100 of size 256
2017-10-04 13:57:25.359565: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac01200 of size 256
2017-10-04 13:57:25.359581: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac01300 of size 2048
2017-10-04 13:57:25.359595: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac01b00 of size 256
2017-10-04 13:57:25.359608: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac01c00 of size 256
2017-10-04 13:57:25.359624: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac01d00 of size 256
2017-10-04 13:57:25.359638: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac01e00 of size 256
2017-10-04 13:57:25.359653: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac01f00 of size 256
2017-10-04 13:57:25.359666: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac02000 of size 256
2017-10-04 13:57:25.359679: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac02100 of size 256
2017-10-04 13:57:25.359695: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac02200 of size 256
2017-10-04 13:57:25.359708: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac02300 of size 256
2017-10-04 13:57:25.359722: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac03f00 of size 256
2017-10-04 13:57:25.359736: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac28000 of size 256
2017-10-04 13:57:25.359749: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ac70100 of size 512
2017-10-04 13:57:25.359765: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ad00300 of size 512
2017-10-04 13:57:25.359780: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ad00500 of size 1179648
2017-10-04 13:57:25.359793: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ae20500 of size 1024
2017-10-04 13:57:25.359807: I tensorflow/core/common_runtime/bfc_allocator.cc:678] Chunk at 0x1041ae20900 of size 3405568
2017-10-04 13:57:25.359821: I tensorflow/core/common_runtime/bfc_allocator.cc:687] Free at 0x1041ac02400 of size 6912
2017-10-04 13:57:25.359835: I tensorflow/core/common_runtime/bfc_allocator.cc:687] Free at 0x1041ac04000 of size 147456
2017-10-04 13:57:25.359849: I tensorflow/core/common_runtime/bfc_allocator.cc:687] Free at 0x1041ac28100 of size 294912
2017-10-04 13:57:25.359863: I tensorflow/core/common_runtime/bfc_allocator.cc:687] Free at 0x1041ac70300 of size 589824
2017-10-04 13:57:25.359878: I tensorflow/core/common_runtime/bfc_allocator.cc:693] Summary of in-use Chunks by size:
2017-10-04 13:57:25.359896: I tensorflow/core/common_runtime/bfc_allocator.cc:696] 19 Chunks of size 256 totalling 4.8KiB
2017-10-04 13:57:25.359913: I tensorflow/core/common_runtime/bfc_allocator.cc:696] 3 Chunks of size 512 totalling 1.5KiB
2017-10-04 13:57:25.359929: I tensorflow/core/common_runtime/bfc_allocator.cc:696] 2 Chunks of size 1024 totalling 2.0KiB
2017-10-04 13:57:25.359944: I tensorflow/core/common_runtime/bfc_allocator.cc:696] 1 Chunks of size 1280 totalling 1.2KiB
2017-10-04 13:57:25.359960: I tensorflow/core/common_runtime/bfc_allocator.cc:696] 1 Chunks of size 2048 totalling 2.0KiB
2017-10-04 13:57:25.359976: I tensorflow/core/common_runtime/bfc_allocator.cc:696] 1 Chunks of size 1179648 totalling 1.12MiB
2017-10-04 13:57:25.359992: I tensorflow/core/common_runtime/bfc_allocator.cc:696] 1 Chunks of size 3405568 totalling 3.25MiB
2017-10-04 13:57:25.360007: I tensorflow/core/common_runtime/bfc_allocator.cc:700] Sum Total of in-use chunks: 4.38MiB
2017-10-04 13:57:25.360028: I tensorflow/core/common_runtime/bfc_allocator.cc:702] Stats:
Limit: 5636096
InUse: 4596992
MaxInUse: 5636096
NumAllocs: 32
MaxAllocSize: 3405568
2017-10-04 13:57:25.360052: W tensorflow/core/common_runtime/bfc_allocator.cc:277] *_*_____*_________****************************************************************xxxxxxxxxxxxxxxxxx
2017-10-04 13:57:25.360084: W tensorflow/core/framework/op_kernel.cc:1192] Resource exhausted: OOM when allocating tensor with shape[3,3,128,256]
I think it has to do with the session and memory leaked but I have no idea how to solve it. Every time I have to delete the container and create a new one just to run one file.
Code:
import numpy
from keras.models import Model, load_model
from keras.preprocessing.image import ImageDataGenerator
from keras.layers import Flatten, Dense, Input, concatenate
from keras.callbacks import ModelCheckpoint, CSVLogger
from sklearn.metrics import confusion_matrix
'''
Model Parameters
'''
# dimensions of our images.
model_name = 'Fuse_Net'
img_width, img_height = 224, 224 # Resolution of inputs
channel = 3
nb_train_samples = 29799
nb_validation_samples = 4428
epochs = 20
batch_size = 40
# Dataset for Stream 1
train_data_dir_1 = '2_Dataset/frontalization/training/'
validation_data_dir_1 = '2_Dataset/frontalization/validation/'
# Dataset for Stream 2
train_data_dir_2 = '2_Dataset/patches/training/'
validation_data_dir_2 = '2_Dataset/patches/validation/'
# Custom parameters
nb_class = 12
hidden_dim = 512
'''
Load the models
'''
vgg_model_frontalization = load_model('weights/Stream_1_Frontalization.hdf5')
vgg_model_patch = load_model('weights/Stream_2_Patches.hdf5')
'''
Customize the model
'''
stream_1 = vgg_model_frontalization.get_layer('pool5').output
stream_1 = Flatten(name='flatten-1')(stream_1)
for layer in vgg_model_frontalization.layers:
layer.name = layer.name + "-model_frontalization"
stream_2 = vgg_model_patch.get_layer('pool5').output
stream_2 = Flatten(name='flatten-2')(stream_2)
for layer in vgg_model_frontalization.layers:
layer.name = layer.name + "-model_patches"
# fuse_layer = stream_1 + stream_2
fuse_layer = concatenate([stream_1, stream_2])
fuse_layer = Dense(hidden_dim, activation='relu', name='fc6')(fuse_layer)
fuse_layer = Dense(hidden_dim, activation='relu', name='fc7')(fuse_layer)
fuse_layer = Dense(hidden_dim, activation='relu', name='fc8')(fuse_layer)
out = Dense(nb_class, activation='softmax', name='fc9')(fuse_layer)
custom_vgg_model = Model(
[vgg_model_frontalization.input, vgg_model_patch.input],
out)
'''
Dataset Generators
'''
train_datagen = ImageDataGenerator(
rescale=1. / 224,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(
rescale=1. / 224)
# Datagen
def obtain_datagen(datagen, train_path, seed_number=7):
return datagen.flow_from_directory(
train_path,
target_size=(img_height, img_width),
batch_size=batch_size,
seed=seed_number,
class_mode='binary')
# Training data generators
train_generator_1 = obtain_datagen(train_datagen, train_data_dir_1)
train_generator_2 = obtain_datagen(train_datagen, train_data_dir_2)
# Validation data generators
validation_generator_1 = obtain_datagen(test_datagen, validation_data_dir_1)
validation_generator_2 = obtain_datagen(test_datagen, validation_data_dir_2)
# Yield for data generators
def generate_data_generator_for_two_images(genX1, genX2):
while True:
X1i = genX1.next()
X2i = genX2 .next()
yield [X1i[0], X2i[0] ], X1i[1]
# Yield for data generators
dataset_train_gen = generate_data_generator_for_two_images(train_generator_1, train_generator_2)
dataset_val_gen = generate_data_generator_for_two_images(validation_generator_1, validation_generator_2)
'''
Fine-tune the model
'''
# Freeze previous layers
for i, layer in enumerate(vgg_model_frontalization.layers):
layer.trainable = False
for i, layer in enumerate(vgg_model_patch.layers):
layer.trainable = False
# Compile the model
custom_vgg_model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
'''
Callbacks
'''
checkpointer = ModelCheckpoint(filepath='weights/'+model_name+'.epoch-{epoch:02d}_val-accu-{val_acc:.2f}.hdf5', verbose=1, save_best_only=True)
csv_logger = CSVLogger('logs/'+model_name+'.log', separator=',', append=False)
'''
Train the model
'''
print('*************************************\nFine-tuning the model \n*************************************')
custom_vgg_model.fit_generator(
dataset_train_gen,
steps_per_epoch=nb_train_samples,
epochs=epochs,
validation_data=dataset_val_gen,
validation_steps=nb_validation_samples,
callbacks=[checkpointer, csv_logger])

Related

Memory Leak in Pytorch Autograd of WGAN-GP

I want to use WGAN-GP, and when I run the code, it gives me an error:
def calculate_gradient_penalty(real_images, fake_images):
t = torch.rand(real_images.size(0), 1, 1, 1).to(real_images.device)
t = t.expand(real_images.size())
interpolates = t * real_images + (1 - t) * fake_images
interpolates.requires_grad_(True)
disc_interpolates = D(interpolates)
grad = torch.autograd.grad(
outputs=disc_interpolates, inputs=interpolates,
grad_outputs=torch.ones_like(disc_interpolates),
create_graph=True, retain_graph=True, allow_unused=True)[0]
grad_norm = torch.norm(torch.flatten(grad, start_dim=1), dim=1)
loss_gp = torch.mean((grad_norm - 1) ** 2) * lambda_term
return loss_gp
RuntimeError Traceback (most recent call
last) in
/opt/conda/lib/python3.8/site-packages/torch/tensor.py in
backward(self, gradient, retain_graph, create_graph, inputs)
243 create_graph=create_graph,
244 inputs=inputs)
--> 245 torch.autograd.backward(self, gradient, retain_graph, create_graph, inputs=inputs)
246
247 def register_hook(self, hook):
/opt/conda/lib/python3.8/site-packages/torch/autograd/init.py in
backward(tensors, grad_tensors, retain_graph, create_graph,
grad_variables, inputs)
143 retain_graph = create_graph
144
--> 145 Variable.execution_engine.run_backward(
146 tensors, grad_tensors, retain_graph, create_graph, inputs,
147 allow_unreachable=True, accumulate_grad=True) # allow_unreachable flag
RuntimeError: CUDA out of memory. Tried to allocate 64.00 MiB (GPU 2;
15.75 GiB total capacity; 13.76 GiB already allocated; 2.75 MiB free; 14.50 GiB reserved in total by PyTorch)
The train code:
%%time
d_progress = []
d_fake_progress = []
d_real_progress = []
penalty = []
g_progress = []
data = get_infinite_batches(benign_data_loader)
one = torch.FloatTensor([1]).to(device)
mone = (one * -1).to(device)
for g_iter in range(generator_iters):
print('----------G Iter-{}----------'.format(g_iter+1))
for p in D.parameters():
p.requires_grad = True # This is by Default
d_loss_real = 0
d_loss_fake = 0
Wasserstein_D = 0
for d_iter in range(critic_iter):
D.zero_grad()
images = data.__next__()
if images.size()[0] != batch_size:
continue
# Train Discriminator
# Real Images
images = images.to(device)
z = torch.randn(batch_size, 100, 1, 1).to(device)
d_loss_real = D(images)
d_loss_real = d_loss_real.mean(0).view(1)
d_loss_real.backward(mone)
# Fake Images
fake_images = G(z)
d_loss_fake = D(fake_images)
d_loss_fake = d_loss_fake.mean(0).view(1)
d_loss_fake.backward(one)
# Calculate Penalty
gradient_penalty = calculate_gradient_penalty(images.data, fake_images.data)
gradient_penalty.backward()
# Total Loss
d_loss = d_loss_fake - d_loss_real + gradient_penalty
Wasserstein_D = d_loss_real - d_loss_fake
d_optimizer.step()
print(f'D Iter:{d_iter+1}/{critic_iter} Loss:{d_loss.detach().cpu().numpy()}')
time.sleep(0.1)
d_progress.append(d_loss) # Store Loss
d_fake_progress.append(d_loss_fake)
d_real_progress.append(d_loss_real)
penalty.append(gradient_penalty)
# Generator Updata
for p in D.parameters():
p.requires_grad = False # Avoid Computation
# Train Generator
# Compute with Fake
G.zero_grad()
z = torch.randn(batch_size, 100, 1, 1).to(device)
fake_images = G(z)
g_loss = D(fake_images)
g_loss = g_loss.mean().mean(0).view(1)
g_loss.backward(one)
# g_cost = -g_loss
g_optimizer.step()
print(f'G Iter:{g_iter+1}/{generator_iters} Loss:{g_loss.detach().cpu().numpy()}')
g_progress.append(g_loss) # Store Loss
Does anyone know how to solve this problem?
All loss tensors which are saved outside of the optimization cycle (i.e. outside the for g_iter in range(generator_iters) loop) need to be detached from the graph. Otherwise, you are keeping all previous computation graphs in memory.
As such, you should detach anything that gets appended to d_progress, d_fake_progress, d_real_progress, penalty, and g_progress.
You can do so by converting the tensor to a scalar value with torch.Tensor.item, the graph will free itself on the following iteration. Change the following lines:
d_progress.append(d_loss) # Store Loss
d_fake_progress.append(d_loss_fake)
d_real_progress.append(d_loss_real)
penalty.append(gradient_penalty)
#######
g_progress.append(g_loss) # Store Loss
to:
d_progress.append(d_loss.item()) # Store Loss
d_fake_progress.append(d_loss_fake.item())
d_real_progress.append(d_loss_real.item())
penalty.append(gradient_penalty.item())
#######
g_progress.append(g_loss.item()) # Store Loss

LSTM fit_generator steps_per_epoch

Because of the large data, I'm using fit_generator with a custom generator to train LSTM model.
I haven't used LSTM with fit_generator before, so I don't know whether my code is correct.
def generator_v2(trainDir,nb_classes,batch_size):
print('start generator')
classes = ["G11","G15","G17","G19","G32","G34","G48","G49"]
while 1:
print('loop generator')
for root, subdirs, files in os.walk(trainDir):
for file in files:
try:
label = root.split("\\")[-1]
label = classes.index(label)
label = to_categorical(label,num_classes=nb_classes).reshape(1,nb_classes)
df = pd.read_csv(root +"\\"+ file)
batches = int(np.ceil(len(df) / batch_size))
for i in range(0, batches):
x_batch = df[i * batch_size:min(len(df), i * batch_size + batch_size)].values
x_batch = x_batch.reshape(1, x_batch.shape[0], x_batch.shape[1])
yield x_batch, label
del df
except EOFError:
print("error" + file)
trainDir = "data_diff_level2_statistics"
nb_classes = 8
batch_size = 128
MaxLen = 449 # each csv file has 449 rows,
batches = int(np.ceil(MaxLen / batch_size))
filesCount = sum([len(files) for r, d, files in os.walk(trainDir)]) # the number of all files
steps_per_epoch = batches*filesCount
model = Sequential()
model.add(LSTM(4,input_shape=(None,5)))
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adadelta',metrics=['acc'])
model.fit_generator(generator_v2(trainDir,nb_classes,batch_size),steps_per_epoch=steps_per_epoch, nb_epoch = 100, verbose=1)
Do I set the correct number of steps_per_epoch?
My all training data shape is : (230,449,5)
So, I set steps_per_epoch with 230 * (449/batch_size).
(449/batch_size) means I read a csv file 128 rows at a time.
The argument steps_per_epoch should be equal to the total number of samples (length of your training set) divided by batch_size(the same is available for validation_steps.
In your example, the length of the dataset is given by dataset_length = number_of_csv_files * length_of_csv_file.
Therefore, your code is correct since you have 230 * (449/batch_size), which is similar to what I have written above.

How to save dpi info in py-opencv?

import cv2
def clear(img):
back = cv2.imread("back.png", cv2.IMREAD_GRAYSCALE)
img = cv2.bitwise_xor(img, back)
ret, img = cv2.threshold(img, 120, 255, cv2.THRESH_BINARY_INV)
return img
def threshold(img):
ret, img = cv2.threshold(img, 120, 255, cv2.THRESH_BINARY_INV)
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
ret, img = cv2.threshold(img, 248, 255, cv2.THRESH_BINARY)
return img
def fomatImage(img):
img = threshold(img)
img = clear(img)
return img
img = fomatImage(cv2.imread("1566135246468.png",cv2.IMREAD_COLOR))
cv2.imwrite("aa.png",img)
This is my code. But when I tried to identify it with tesseract-ocr, I got a warning.
Warning: Invalid resolution 0 dpi. Using 70 instead.
How should I set up dpi?
AFAIK, OpenCV doesn't set the dpi of PNG files it writes, so you are looking at work-arounds. Here are some ideas...
Method 1 - Use PIL/Pillow instead of OpenCV
PIL/Pillow can write dpi information into PNG files. So you would:
Step 1 - Convert your BGR OpenCV image into RGB to match PIL's channel ordering
from PIL import Image
RGBimage = cv2.cvtColor(BGRimage, cv2.COLOR_BGR2RGB)
Step 2 - Convert OpenCV Numpy array onto PIL Image
PILimage = Image.fromarray(RGBimage)
Step 3 - Write with PIL
PILimage.save('result.png', dpi=(72,72))
As Fred mentions in the comments, you could equally use Python Wand in much the same way.
Method 2 - Write with OpenCV but modify afterwards with some tool
You could use Python's subprocess module to shell out to, say, ImageMagick and set the dpi like this:
magick OpenCVImage.png -set units pixelspercentimeter -density 28.3 result.png
All you need to know is that PNG uses metric (dots per centimetre) rather than imperial (dots per inch) and there are 2.54cm in an inch, so 72 dpi becomes 28.3 dots per cm.
If your ImageMagick version is older than v7, replace magick with convert.
Method 3 - Write with OpenCV and insert dpi yourself
You could write your file to memory using OpenCV's imencode(). Then search in the file for the IDAT (image data) chunk - which is the one containing the image pixels and insert a pHYs chunk before that which sets the density. Then write to disk.
It's not that hard actually - it's just 9 bytes, see here and also look at pngcheck output at end of answer.
This code is not production tested but seems to work pretty well for me:
#!/usr/bin/env python3
import struct
import numpy as np
import cv2
import zlib
def writePNGwithdpi(im, filename, dpi=(72,72)):
"""Save the image as PNG with embedded dpi"""
# Encode as PNG into memory
retval, buffer = cv2.imencode(".png", im)
s = buffer.tostring()
# Find start of IDAT chunk
IDAToffset = s.find(b'IDAT') - 4
# Create our lovely new pHYs chunk - https://www.w3.org/TR/2003/REC-PNG-20031110/#11pHYs
pHYs = b'pHYs' + struct.pack('!IIc',int(dpi[0]/0.0254),int(dpi[1]/0.0254),b"\x01" )
pHYs = struct.pack('!I',9) + pHYs + struct.pack('!I',zlib.crc32(pHYs))
# Open output filename and write...
# ... stuff preceding IDAT as created by OpenCV
# ... new pHYs as created by us above
# ... IDAT onwards as created by OpenCV
with open(filename, "wb") as out:
out.write(buffer[0:IDAToffset])
out.write(pHYs)
out.write(buffer[IDAToffset:])
################################################################################
# main
################################################################################
# Load sample image
im = cv2.imread('lena.png')
# Save at specific dpi
writePNGwithdpi(im, "result.png", (32,300))
Whichever method you use, you can use pngcheck --v image.png to check what you have done:
pngcheck -vv a.png
Sample Output
File: a.png (306 bytes)
chunk IHDR at offset 0x0000c, length 13
100 x 100 image, 1-bit palette, non-interlaced
chunk gAMA at offset 0x00025, length 4: 0.45455
chunk cHRM at offset 0x00035, length 32
White x = 0.3127 y = 0.329, Red x = 0.64 y = 0.33
Green x = 0.3 y = 0.6, Blue x = 0.15 y = 0.06
chunk PLTE at offset 0x00061, length 6: 2 palette entries
chunk bKGD at offset 0x00073, length 1
index = 1
chunk pHYs at offset 0x00080, length 9: 255x255 pixels/unit (1:1). <-- THIS SETS THE DENSITY
chunk tIME at offset 0x00095, length 7: 19 Aug 2019 10:15:00 UTC
chunk IDAT at offset 0x000a8, length 20
zlib: deflated, 2K window, maximum compression
row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
(100 out of 100)
chunk tEXt at offset 0x000c8, length 37, keyword: date:create
chunk tEXt at offset 0x000f9, length 37, keyword: date:modify
chunk IEND at offset 0x0012a, length 0
No errors detected in a.png (11 chunks, 76.5% compression).
While I am editing PNG chunks, I also managed to set a tIME chunk and a tEXt chunk with the Author. They go like this:
# Create a new tIME chunk - https://www.w3.org/TR/2003/REC-PNG-20031110/#11tIME
year, month, day, hour, min, sec = 2020, 12, 25, 12, 0, 0 # Midday Christmas day 2020
tIME = b'tIME' + struct.pack('!HBBBBB',year,month,day,hour,min,sec)
tIME = struct.pack('!I',7) + tIME + struct.pack('!I',zlib.crc32(tIME))
# Create a new tEXt chunk - https://www.w3.org/TR/2003/REC-PNG-20031110/#11tEXt
Author = "Author\x00Sir Mark The Great"
tEXt = b'tEXt' + bytes(Author.encode('ascii'))
tEXt = struct.pack('!I',len(Author)) + tEXt + struct.pack('!I',zlib.crc32(tEXt))
# Open output filename and write...
# ... stuff preceding IDAT as created by OpenCV
# ... new pHYs as created by us above
# ... new tIME as created by us above
# ... new tEXt as created by us above
# ... IDAT onwards as created by OpenCV
with open(filename, "wb") as out:
out.write(buffer[0:IDAToffset])
out.write(pHYs)
out.write(tIME)
out.write(tEXt)
out.write(buffer[IDAToffset:])
Keywords: OpenCV, PIL, Pillow, dpi, density, imwrite, PNG, chunks, pHYs chunk, Python, image, image-processing, tEXt chunk, tIME chunk, author, comment

Deep Conv Model number of parameters

I was reading this claim:
A CNN with two 5x5 convolution layers (the first with 32 channels, the
second with 64, each followed with 2x2 max pooling), a fully connected
layer with 512 units and ReLu activation, and a final softmax output
layer (1,663,370 total parameters)
I don't see how they calculate 1.6m parameters. The same network implementation gives me ~ 580k parameters which is more realistic given that this is a small network.
Assuming you are talking about MNIST images, 1 input channel, stride=1, padding=2
INPUT: [28x28x1] weights: 0
CONV5-32: [28x28x32] weights: (1*5*5)*32 + 32 = 832
POOL2: [14x14x32] weights: 0
CONV5-64: [14x14x64] weights: (5*5*32)*64 + 64 = 51,264
POOL2: [7x7x64] weights: 0
FC: [1x1x512] weights: 7*7*64*512 + 512 = 1,606,144
Softmax: [1x1x10] weights: 512*10 + 10 = 5,130
-----------------------------------------------------------
1,663,370
Consider this cheating, but here is how 1663370 is obtained:
import torch.nn as nn
#First fully-connected (linear) layer input size as in the accepted answer:
linear_in = 7*7*64
model = nn.Sequential(
nn.Conv2d(1,32,5),
nn.MaxPool2d(2,2),
nn.Conv2d(32,64,5),
nn.MaxPool2d(2,2),
nn.Linear(linear_in, 512),
nn.ReLU(),
nn.Linear(512,10)
)
Now, the parameters:
sum([p.numel() for p in model.parameters()])
1663370
Layer by Layer:
for p in model.parameters():
print(p.size())
print(p.numel())
torch.Size([32, 1, 5, 5])
800
torch.Size([32])
32
torch.Size([64, 32, 5, 5])
51200
torch.Size([64])
64
torch.Size([512, 3136])
1605632
torch.Size([512])
512
torch.Size([10, 512])
5120
torch.Size([10])
10

Tensorflow BiRNN dynamic dimension size for input data

I have issue with constructing Input data for BiRNN network.
I'm create License Plate detection system like described : https://arxiv.org/pdf/1601.05610v1.pdf
I have got to "4.2.3 Sequence Labelling" part where I need to train BiRNN with dataset of (total_count_of_images, None, 256) shape, None because it's length of image and and it is different for every picture in data set.
Let's say I have 3000 Images. Then shape would look like :
train.shape : (3000,) but really it is (3000, None, 256) !?
So I got example code from
https://github.com/aymericdamien/TensorFlow-Examples/blob/master/notebooks/3_NeuralNetworks/bidirectional_rnn.ipynb
So I'm struggling even with starting to train my RNN. I don't understand how I need to constrct input data/model, input placeholders, variables etc to achieve any training process.
As far as I know everything should work. My code :
reset_graph()
'''
Dataset : (10000, 784)
Labels : (10000, 10)
To classify images using a bidirectional reccurent neural network, we consider
every image row as a sequence of pixels. Because MNIST image shape is 28*28px,
we will then handle 28 sequences of 28 steps for every sample.
'''
# Parameters
learning_rate = 0.001
training_iters = 100 # 100000
display_step = 10
batch_size = 40
# Network Parameters
n_input = 256 # data inpit size/256D
n_steps = 256 # timesteps
n_hidden = 200 # hidden layer num of features
n_classes = 36 # MNIST total classes (0-9 digits and a-z letters)
# tf Graph input
x = tf.placeholder("float", [batch_size, None , n_input], name='input_placeholder')
y = tf.placeholder("float", [batch_size, None, n_classes], name='labels_placeholder')
# Define weights
weights = {
# Hidden layer weights => 2*n_hidden because of foward + backward cells
'out': tf.Variable(tf.random_normal([2*n_hidden, n_classes]))
}
biases = {
'out': tf.Variable(tf.random_normal([n_classes]))
}
def BiRNN(x, weights, biases):
print('Input x',x.get_shape().as_list())
print('weights[\'out\']', weights['out'].get_shape().as_list())
print('biases[\'out\']', biases['out'].get_shape().as_list())
# Prepare data shape to match `bidirectional_rnn` function requirements
# Current data input shape: (batch_size, n_steps, n_input)
# Required shape: 'n_steps' tensors list of shape (batch_size, n_input)
# Permuting batch_size and n_steps
#x = tf.transpose(x, [1, 0, 2])
#print('Transposed x',x.get_shape().as_list())
# Reshape to (n_steps*batch_size, n_input)
x = tf.reshape(x, [-1, n_steps])
print('Reshaped x',x.get_shape().as_list())
# Split to get a list of 'n_steps' tensors of shape (batch_size, n_input)
x = tf.split(0, n_input, x)
print(len(x),'of [ ',x[0],' ] kinds')
# Define lstm cells with tensorflow
# Forward direction cell
lstm_fw_cell = tf.nn.rnn_cell.BasicLSTMCell(n_hidden, forget_bias=1.0, state_is_tuple=True)
# Backward direction cell
lstm_bw_cell = tf.nn.rnn_cell.BasicLSTMCell(n_hidden, forget_bias=1.0, state_is_tuple=True)
# Get lstm cell output
outputs, _, _ = rnn.bidirectional_rnn(lstm_fw_cell, lstm_bw_cell, x, dtype=tf.float32)
print( len(outputs),'of [ ',outputs[0],' ] kinds' )
# Linear activation, using rnn inner loop last output
ret = tf.matmul(outputs[-1], weights['out']) + biases['out']
print('ret', ret.get_shape().as_list())
return ret
pred = BiRNN(x, weights, biases)
# Define loss and optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
# Evaluate model
correct_pred = tf.equal(tf.argmax(pred,1), tf.argmax(y,1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
# Initializing the variables
init = tf.initialize_all_variables()
OUTPUT :
Input x [40, None, 256]
weights['out'] [400, 36]
biases['out'] [36]
Reshaped x [None, 256]
256 of [ Tensor("split:0", shape=(?, 256), dtype=float32) ] kinds
256 of [ Tensor("concat:0", shape=(?, 400), dtype=float32) ] kinds
ret [None, 36]
Everything just right there.
Problems start at session part :
# Launch the graph
with tf.Session() as sess:
sess.run(init)
step = 1
batch_data = batch_gen(batch_size)
# Keep training until reach max iterations
while step * batch_size < training_iters:
batch_x, batch_y = next(batch_data)
print(batch_x.shape)
print(batch_y.shape)
#m[:,0, None, None].shape
#Run optimization op (backprop)
print('Optimizer')
sess.run(optimizer, feed_dict={x: batch_x, y: batch_y})
if step % display_step == 0:
print('Display')
# Calculate batch accuracy
acc = sess.run(accuracy, feed_dict={x: batch_x, y: batch_y})
# Calculate batch loss
loss = sess.run(cost, feed_dict={x: batch_x, y: batch_y})
print("Iter " + str(step * batch_size) + ", Minibatch Loss= " + \
"{:.6f}".format(loss) + ", Training Accuracy= " + \
"{:.5f}".format(acc))
step += 1
print("Optimization Finished!")
# Calculate accuracy for 128 mnist test images
test_len = 128
test_data = mnist.test.images[:test_len].reshape((-1, n_steps, n_input))
test_label = mnist.test.labels[:test_len]
print("Testing Accuracy:", \
sess.run(accuracy, feed_dict={x: test_data, y: test_label}))
There I got following error :
(40,)
(40,)
Optimizer
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-96-a53814db8181> in <module>()
14 #Run optimization op (backprop)
15 print('Optimizer')
---> 16 sess.run(optimizer, feed_dict={x: batch_x, y: batch_y})
17
18 if step % display_step == 0:
/home/nauris/anaconda3/lib/python3.5/site-packages/tensorflow/python/client/session.py in run(self, fetches, feed_dict, options, run_metadata)
715 try:
716 result = self._run(None, fetches, feed_dict, options_ptr,
--> 717 run_metadata_ptr)
718 if run_metadata:
719 proto_data = tf_session.TF_GetBuffer(run_metadata_ptr)
/home/nauris/anaconda3/lib/python3.5/site-packages/tensorflow/python/client/session.py in _run(self, handle, fetches, feed_dict, options, run_metadata)
886 ' to a larger type (e.g. int64).')
887
--> 888 np_val = np.asarray(subfeed_val, dtype=subfeed_dtype)
889
890 if not subfeed_t.get_shape().is_compatible_with(np_val.shape):
/home/nauris/anaconda3/lib/python3.5/site-packages/numpy/core/numeric.py in asarray(a, dtype, order)
480
481 """
--> 482 return array(a, dtype, copy=False, order=order)
483
484 def asanyarray(a, dtype=None, order=None):
ValueError: setting an array element with a sequence.
Any help would be highly appreciated. Thanks everyone in advance.
Realized that error occurs because you cannot feed numpy ndarray with inconsistent dimensions such as (3000, None, 256) in my case. Haven't found any solution yet.

Resources