Related
I am trying to create a generative network based on the pre-trained Inception_v3.
1) I fix all the weights in the model
2) create a Variable whose size is (2, 3, 299, 299)
3) create targets of size (2, 1000) that I want my final layer activations to become as close as possible to by optimizing the Variable.
(I do not set the batchsize of 1, because unlike VGG16, Inception_v3 doesn't take batchsize=1, but that's not the point).
The following code should work, but gives me the error: «RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation».
# minimalist code with Inception_v3 that throws the error:
import torch
from torch.autograd import Variable
import torch.optim as optim
import torch.nn as nn
import torchvision
torch.set_default_tensor_type('torch.FloatTensor')
Iv3 = torchvision.models.inception_v3(pretrained=True)
for i in Iv3.parameters():
i.requires_grad = False
criterion = nn.CrossEntropyLoss()
x = Variable(torch.randn(2, 3, 299, 299), requires_grad=True)
target = torch.empty(2, dtype=torch.long).random_(1000)
output = Iv3(x)
loss = criterion(output[0], target)
loss.backward()
print(x.grad)
This is very strange, because if I do the same thing with VGG16, everything works fine:
# minimalist working code with VGG16:
import torch
from torch.autograd import Variable
import torch.optim as optim
import torch.nn as nn
import torchvision
# torch.cuda.empty_cache()
# vgg16 = torchvision.models.vgg16(pretrained=True).cuda()
# torch.set_default_tensor_type('torch.cuda.FloatTensor')
torch.set_default_tensor_type('torch.FloatTensor')
vgg16 = torchvision.models.vgg16(pretrained=True)
for i in vgg16.parameters():
i.requires_grad = False
criterion = nn.CrossEntropyLoss()
x = Variable(torch.randn(2, 3, 229, 229), requires_grad=True)
target = torch.empty(2, dtype=torch.long).random_(1000)
output = vgg16(x)
loss = criterion(output, target)
loss.backward()
print(x.grad)
Please help.
Thanks to #iacolippo the issue is solved. Turns out the problem was due to Pytorch 1.0.0. No problem with Pytorch 0.4.1. though.
I have some tests that work with graph and sessions. I also want to write some small tests with eager mode to test easily some functionalities. For example:
def test_normal_execution():
matrix_2x4 = np.array([[1, 2, 3, 4], [6, 7, 8, 9]])
dataset = tf.data.Dataset.from_tensor_slices(matrix_2x4)
iterator = dataset.make_one_shot_iterator()
first_elem = iterator.get_next()
with tf.Session() as sess:
result = sess.run(first_elem)
assert (result == [1, 2, 3, 4]).all()
sess.close()
In another file:
def test_eager_execution():
matrix_2x4 = np.array([[1, 2, 3, 4], [6, 7, 8, 9]])
tf.enable_eager_execution()
dataset = tf.data.Dataset.from_tensor_slices(matrix_2x4)
iterator = dataset.__iter__()
first_elem = iterator.next()
assert (first_elem.numpy() == [1, 2, 3, 4]).all()
Is there a way to to this? I get ValueError: tf.enable_eager_execution must be called at program startup. when I try to run the test executed eagerly. I am using pytest to run my tests.
edit:
With little assistance from the accepted response I created a decorator, that works nicely with eager mode and pytest's fixtures:
def run_eagerly(func):
#functools.wraps(func)
def eager_fun(*args, **kwargs):
with tf.Session() as sess:
sess.run(tfe.py_func(func, inp=list(kwargs.values()), Tout=[]))
return eager_fun
With the caveat that anything in the tf.contrib namespace is subject to change between releases, you can decorate your test with #tf.contrib.eager.run_test_in_graph_and_eager_modes. Some other projects, like TensorFlow Probability seem to use this.
For non-tests, some things to look into are:
tf.contrib.eager.defun: Is useful when you have eager execution enabled but want to "compile" some computation into a graph to benefit from memory and/or performance optimizations.
tf.contrib.eager.py_func: Is useful when do not have eager execution enabled but want to execute some computation in the graph as a Python function.
One may question the reasoning behind not allowing a call to tf.enable_eager_execution() to be undone. The idea is that library authors should not invoke it, only the end-user should invoke it in main(). The reduces the chances that libraries are written incompatible ways (where say functions in one library disable eager execution and return symbolic tensors while functions in another library enable eager execution and expects concrete valued tensors. This would make mixing the libraries problematic).
Hope that helps
There is an official way to use eager execution in a graph environment. But I'm not sure if this is good and convenient enough for you because you need to write quite some code to wrap and run your test function. Anyway, here is your example which should at least work:
import numpy as np
import tensorflow as tf
def test_normal_execution():
matrix_2x4 = np.array([[1, 2, 3, 4], [6, 7, 8, 9]])
dataset = tf.data.Dataset.from_tensor_slices(matrix_2x4)
iterator = dataset.make_one_shot_iterator()
first_elem = iterator.get_next()
with tf.Session() as sess:
result = sess.run(first_elem)
assert (result == [1, 2, 3, 4]).all()
sess.close()
def test_eager_execution():
matrix_2x4 = np.array([[1, 2, 3, 4], [6, 7, 8, 9]])
dataset = tf.data.Dataset.from_tensor_slices(matrix_2x4)
iterator = dataset.__iter__()
first_elem = iterator.next()
assert (first_elem.numpy() == [1, 2, 3, 4]).all()
test_normal_execution()
# test_eager_execution() # Instead, you have to use the following three lines.
with tf.Session() as sess:
tfe = tf.contrib.eager
sess.run(tfe.py_func(test_eager_execution, [], []))
Somewhat undocumented but tensorflow 2 has a function run_all_in_graph_and_eager_modes used for decorating test classes and
run_in_graph_and_eager_modes used for decorating test methods:
import tensorflow as tf
from tensorflow.python.framework import test_util
#test_util.run_all_in_graph_and_eager_modes
class MyTestCase(tf.test.TestCase):
#...
import tensorflow as tf
from tensorflow.python.framework import test_util
class MyTestCase(tf.test.TestCase):
#test_util.run_in_graph_and_eager_modes
def test_something():
#...
I've been working with the Tensorflow Object Detection API - In my case, I'm attempting to detect vehicles in still images using the kitti-trained model (faster_rcnn_resnet101_kitti_2018_01_28) from the model zoo and I am using code modified from the object_detection_tutorial jupyter notebook included in the github repository .
I have included my modified code below but am finding the same results with the original notebook from github.
When running on a jupyter notebook server on an Amazon AWS g3x4large (GPU) instance with the deep learning AMI, it takes just shy of 4 seconds to process a single image. The time for the inference function is 1.3-1.5 seconds (see code below) - which seems ABNORMALLY high for the reported inference times for the model (20ms). While I don't expect to hit the reported mark, my times seem out of line and are impractical for my needs. I'm looking at processing 1-million+ images at a time and can't afford 46 days of processing time. Given that the model is used on video frame captures....I would think it should be possible to cut time per image to under 1 second, at least.
My questions are:
1) What explanations/solutions exist to reduce inference time?
2) Is 1.5 seconds to convert an image to a numpy (prior to processing) out-of-line?
3) If this is the best performance I can expect, how much increase in time could I hope to gain from reworking the model to batch process images?
Thanks for any help!
Code from python notebook:
import numpy as np
import os
import six.moves.urllib as urllib
import sys
import tarfile
import tensorflow as tf
import zipfile
import json
import collections
import os.path
import datetime
from collections import defaultdict
from io import StringIO
from matplotlib import pyplot as plt
from PIL import Image
# This is needed since the notebook is stored in the object_detection folder.
sys.path.append("..")
# This is needed to display the images.
get_ipython().magic('matplotlib inline')
#Setup variables
PATH_TO_TEST_IMAGES_DIR = 'test_images'
MODEL_NAME = 'faster_rcnn_resnet101_kitti_2018_01_28'
# Path to frozen detection graph. This is the actual model that is used for the object detection.
PATH_TO_CKPT = MODEL_NAME + '/frozen_inference_graph.pb'
# List of the strings that is used to add correct label for each box.
PATH_TO_LABELS = os.path.join('data', 'kitti_label_map.pbtxt')
NUM_CLASSES = 2
from utils import label_map_util
from utils import visualization_utils as vis_util
def get_scores(
boxes,
classes,
scores,
category_index,
min_score_thresh=.5
):
import collections
# Create a display string (and color) for every box location, group any boxes
# that correspond to the same location.
box_to_display_str_map = collections.defaultdict(list)
for i in range(boxes.shape[0]):
if scores is None or scores[i] > min_score_thresh:
box = tuple(boxes[i].tolist())
if scores is None:
box_to_color_map[box] = groundtruth_box_visualization_color
else:
display_str = ''
if classes[i] in category_index.keys():
class_name = category_index[classes[i]]['name']
else:
class_name = 'N/A'
display_str = str(class_name)
if not display_str:
display_str = '{}%'.format(int(100*scores[i]))
else:
display_str = '{}: {}%'.format(display_str, int(100*scores[i]))
box_to_display_str_map[i].append(display_str)
return box_to_display_str_map
def load_image_into_numpy_array(image):
(im_width, im_height) = image.size
return np.array(image.getdata()).reshape(
(im_height, im_width, 3)).astype(np.uint8)
def run_inference_for_single_image(image, graph):
with graph.as_default():
with tf.Session() as sess:
# Get handles to input and output tensors
ops = tf.get_default_graph().get_operations()
all_tensor_names = {output.name for op in ops for output in op.outputs}
tensor_dict = {}
for key in [
'num_detections', 'detection_boxes', 'detection_scores',
'detection_classes', 'detection_masks'
]:
tensor_name = key + ':0'
if tensor_name in all_tensor_names:
tensor_dict[key] = tf.get_default_graph().get_tensor_by_name(
tensor_name)
if 'detection_masks' in tensor_dict:
# The following processing is only for single image
detection_boxes = tf.squeeze(tensor_dict['detection_boxes'], [0])
detection_masks = tf.squeeze(tensor_dict['detection_masks'], [0])
# Reframe is required to translate mask from box coordinates to image coordinates and fit the image size.
real_num_detection = tf.cast(tensor_dict['num_detections'][0], tf.int32)
detection_boxes = tf.slice(detection_boxes, [0, 0], [real_num_detection, -1])
detection_masks = tf.slice(detection_masks, [0, 0, 0], [real_num_detection, -1, -1])
detection_masks_reframed = utils_ops.reframe_box_masks_to_image_masks(
detection_masks, detection_boxes, image.shape[0], image.shape[1])
detection_masks_reframed = tf.cast(
tf.greater(detection_masks_reframed, 0.5), tf.uint8)
# Follow the convention by adding back the batch dimension
tensor_dict['detection_masks'] = tf.expand_dims(
detection_masks_reframed, 0)
image_tensor = tf.get_default_graph().get_tensor_by_name('image_tensor:0')
# Run inference
output_dict = sess.run(tensor_dict,
feed_dict={image_tensor: np.expand_dims(image, 0)})
# all outputs are float32 numpy arrays, so convert types as appropriate
output_dict['num_detections'] = int(output_dict['num_detections'][0])
output_dict['detection_classes'] = output_dict[
'detection_classes'][0].astype(np.uint8)
output_dict['detection_boxes'] = output_dict['detection_boxes'][0]
output_dict['detection_scores'] = output_dict['detection_scores'][0]
if 'detection_masks' in output_dict:
output_dict['detection_masks'] = output_dict['detection_masks'][0]
return output_dict
#get list of paths
exten='.jpg'
TEST_IMAGE_PATHS=[]
for dirpath, dirnames, files in os.walk(PATH_TO_TEST_IMAGES_DIR):
for name in files:
if name.lower().endswith(exten):
#print(os.path.join(dirpath,name))
TEST_IMAGE_PATHS.append(os.path.join(dirpath,name))
print((len(TEST_IMAGE_PATHS), 'Images To Process'))
#load model graph for inference
detection_graph = tf.Graph()
with detection_graph.as_default():
od_graph_def = tf.GraphDef()
with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
serialized_graph = fid.read()
od_graph_def.ParseFromString(serialized_graph)
tf.import_graph_def(od_graph_def, name='')
#setup class labeling parameters
label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
category_index = label_map_util.create_category_index(categories)
#placeholder for timings
myTimings=[]
myX = 1
myResults = collections.defaultdict(list)
for image_path in TEST_IMAGE_PATHS:
if os.path.exists(image_path):
print(myX,"--------------------------------------",datetime.datetime.time(datetime.datetime.now()))
print(myX,"Image:", image_path)
myTimings.append((myX,"Image", image_path))
print(myX,"Open:",datetime.datetime.time(datetime.datetime.now()))
myTimings.append((myX,"Open",datetime.datetime.time(datetime.datetime.now()).__str__()))
image = Image.open(image_path)
# the array based representation of the image will be used later in order to prepare the
# result image with boxes and labels on it.
print(myX,"Numpy:",datetime.datetime.time(datetime.datetime.now()))
myTimings.append((myX,"Numpy",datetime.datetime.time(datetime.datetime.now()).__str__()))
image_np = load_image_into_numpy_array(image)
# Expand dimensions since the model expects images to have shape: [1, None, None, 3]
print(myX,"Expand:",datetime.datetime.time(datetime.datetime.now()))
myTimings.append((myX,"Expand",datetime.datetime.time(datetime.datetime.now()).__str__()))
image_np_expanded = np.expand_dims(image_np, axis=0)
# Actual detection.
print(myX,"Detect:",datetime.datetime.time(datetime.datetime.now()))
myTimings.append((myX,"Detect",datetime.datetime.time(datetime.datetime.now()).__str__()))
output_dict = run_inference_for_single_image(image_np, detection_graph)
# Visualization of the results of a detection.
print(myX,"Export:",datetime.datetime.time(datetime.datetime.now()))
myTimings.append((myX,"Export",datetime.datetime.time(datetime.datetime.now()).__str__()))
op=get_scores(
output_dict['detection_boxes'],
output_dict['detection_classes'],
output_dict['detection_scores'],
category_index,
min_score_thresh=.2)
myResults[image_path].append(op)
print(myX,"Done:", datetime.datetime.time(datetime.datetime.now()))
myTimings.append((myX,"Done", datetime.datetime.time(datetime.datetime.now()).__str__()))
myX= myX + 1
#save results
with open((OUTPUTS_BASENAME+'_Results.json'), 'w') as fout:
json.dump(myResults, fout)
with open((OUTPUTS_BASENAME+'_Timings.json'), 'w') as fout:
json.dump(myTimings, fout)
Example Of Timings:
[1, "Image", "test_images/DE4T_11Jan2018/MFDC4612.JPG"]
[1, "Open", "19:20:08.029423"]
[1, "Numpy", "19:20:08.052679"]
[1, "Expand", "19:20:09.977166"]
[1, "Detect", "19:20:09.977250"]
[1, "Export", "19:23:13.902443"]
[1, "Done", "19:23:13.903012"]
[2, "Image", "test_images/DE4T_11Jan2018/MFDC4616.JPG"]
[2, "Open", "19:23:13.903885"]
[2, "Numpy", "19:23:13.906320"]
[2, "Expand", "19:23:15.756308"]
[2, "Detect", "19:23:15.756597"]
[2, "Export", "19:23:17.153233"]
[2, "Done", "19:23:17.153699"]
[3, "Image", "test_images/DE4T_11Jan2018/MFDC4681.JPG"]
[3, "Open", "19:23:17.154510"]
[3, "Numpy", "19:23:17.156576"]
[3, "Expand", "19:23:19.012935"]
[3, "Detect", "19:23:19.013013"]
[3, "Export", "19:23:20.323839"]
[3, "Done", "19:23:20.324307"]
[4, "Image", "test_images/DE4T_11Jan2018/MFDC4697.JPG"]
[4, "Open", "19:23:20.324791"]
[4, "Numpy", "19:23:20.327136"]
[4, "Expand", "19:23:22.175578"]
[4, "Detect", "19:23:22.175658"]
[4, "Export", "19:23:23.472040"]
[4, "Done", "19:23:23.472297"]
1) What you can do is load the video directly instead of images, then change "run_inference_for_single_image()" to create the session once and load the images/video in it (re-creating the graph is very slow). Furthermore, you can edit the pipeline config file to reduce the number of proposals, which will directly speedup inference. Note you have to re-export the graph afterwards (https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/exporting_models.md). Batch also helps (though I am sorry, I forgot by how much) and finally, you can employ multiprocessing to offload CPU specific operations (drawing bounding boxes, loading data) to utilize the GPU better.
2) Is 1.5 seconds to convert an image to a numpy (prior to processing) out-of-line <- yes, that is insanely slow and there is plenty of room for improvement.
3) While I don't know the exact gpu at AWS (k80?), you should be able to get over 10fps on a geforce 1080TI with all fixes, which is in line with the 79ms time they reported (where did you get 20ms for faster-rcnn_resnet_101?? )
You could also try OpenVINO for better performance of the inference. It optimizes the inference time by e.g. graph pruning and fusing some operations. OpenVINO is optimized for Intel hardware but it should work with any CPU (even with Cloud).
Here are some performance benchmarks for the Faster RCNN Resnet model and various CPUs.
It's rather straightforward to convert the Tensorflow model to OpenVINO unless you have fancy custom layers. The full tutorial on how to do it can be found here. Some snippets below.
Install OpenVINO
The easiest way to do it is using PIP. Alternatively, you can use this tool to find the best way in your case.
pip install openvino-dev[tensorflow2]
Use Model Optimizer to convert SavedModel model
The Model Optimizer is a command-line tool that comes from OpenVINO Development Package. It converts the Tensorflow model to IR, which is a default format for OpenVINO. You can also try the precision of FP16, which should give you better performance without a significant accuracy drop (just change data_type). Run in the command line:
mo --saved_model_dir "model" --input_shape "[1, 3, 224, 224]" --data_type FP32 --output_dir "model_ir"
Run the inference
The converted model can be loaded by the runtime and compiled for a specific device e.g. CPU or GPU (integrated into your CPU like Intel HD Graphics). If you don't know what is the best choice for you, just use AUTO.
# Load the network
ie = Core()
model_ir = ie.read_model(model="model_ir/model.xml")
compiled_model_ir = ie.compile_model(model=model_ir, device_name="CPU")
# Get output layer
output_layer_ir = compiled_model_ir.output(0)
# Run inference on the input image
result = compiled_model_ir([input_image])[output_layer_ir]
There is even [OpenVINO Model Server][5] which is very similar to Tensorflow Serving.
Disclaimer: I work on OpenVINO.
On my network, a scheduled report creates a new directory (with random numbers) every time it runs and then places a CSV file inside it. I currently fetch files over SMB using pysmbclient, but I'm not sure how I can navigate to this reports latest directory with what the modules Glob returns (below).
How can I get to the last created directory, do I need to parse the datetime.datetime's first somehow? Here's what I have:
import smbclient
import glob
import os
smb = smbclient.SambaClient(server=uk51, ip=10.10.10.10, share="share",
username="test", password="password", domain='office')
# recent = smb.glob(max(glob.iglob(\\*)), key=os.path.getctime)) # Latest directory
# smb.download(recent + "summary.csv", "/usr/reports/uk51.csv")) # Download latest dir's CSV
example = smb.glob('\\*')
print list(example) # Example of what Glob returns
#> python script.py
#> [(u'1192957', u'D', 0, datetime.datetime(2017, 4, 23, 10, 29, 20)), (u'1193044', u'D', 0, datetime.datetime(2017, 4, 24, 10, 29, 22))]
Those 4-tuples are how pysmbclient returns data from smb.glob(). You don't need to parse the datetimes as they are already datetime.datetime objects which can be sorted as you would usually sort things. To get the final (3rd) value in each 4-tuple you can use operator.itemgetter:
import operator as op
#example = [(u'1193044', u'D', 0, datetime.datetime(2017, 4, 24, 10, 29, 22)),
# (u'1192957', u'D', 0, datetime.datetime(2017, 4, 23, 10, 29, 20))]
example = list(smb.glob('\\*'))
example.sort(key=op.itemgetter(3),reverse=True)
most_recent_dir = example[0][0] # to get the most recent directory name
And then you would use os.path.join to build up the path to download:
import os
smb.download(os.path.join(most_recent_dir,"summary.csv"), "/usr/reports/uk51.csv")
I have been trying to run the code below which I got from here and even though I have changed almost nothing other than the image size (350,350 instead of 150, 150) is still cannot get it to work. I am getting the above filter error (in title) which I do comprehend but I am not doing it wrong so I don't understand this. It basically says that I cannot have more nodes than inputs, correct?
I was able to eventually hack my way to a solution by changing this line:
model.add(Convolution2D(32, 5, 5, border_mode='valid', input_shape=(3, IMG_WIDTH, IMG_HEIGHT)))
with this:
model.add(Convolution2D(32, 5, 5, border_mode='valid', input_shape=(IMG_WIDTH, IMG_HEIGHT, 3)))
but I would still like to understand why this worked.
Here is the code below along with the error I am getting. Would appreciate some help (I am using Python Anaconda 2.7.11).
# IMPORT LIBRARIES --------------------------------------------------------------------------------#
import glob
import tensorflow
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from settings import RAW_DATA_ROOT
# GLOBAL VARIABLES --------------------------------------------------------------------------------#
TRAIN_PATH = RAW_DATA_ROOT + "/train/"
TEST_PATH = RAW_DATA_ROOT + "/test/"
IMG_WIDTH, IMG_HEIGHT = 350, 350
NB_TRAIN_SAMPLES = len(glob.glob(TRAIN_PATH + "*"))
NB_VALIDATION_SAMPLES = len(glob.glob(TEST_PATH + "*"))
NB_EPOCH = 50
# FUNCTIONS ---------------------------------------------------------------------------------------#
def baseline_model():
"""
The Keras library provides wrapper classes to allow you to use neural network models developed
with Keras in scikit-learn. The code snippet below is used to construct a simple stack of 3
convolution layers with a ReLU activation and followed by max-pooling layers. This is very
similar to the architectures that Yann LeCun advocated in the 1990s for image classification
(with the exception of ReLU).
:return: The training model.
"""
model = Sequential()
model.add(Convolution2D(32, 5, 5, border_mode='valid', input_shape=(3, IMG_WIDTH, IMG_HEIGHT)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(32, 5, 5, border_mode='valid'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(64, 5, 5, border_mode='valid'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
# Add a fully connected layer layer that converts our 3D feature maps to 1D feature vectors
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
# Use a dropout layer to reduce over-fitting, by preventing a layer from seeing twice the exact
# same pattern (works by switching off a node once in a while in different epochs...). This
# will also serve as out output layer.
model.add(Dropout(0.5))
model.add(Dense(8))
model.add(Activation('softmax'))
# Compile model
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
return model
def train_model(model):
"""
Simple script that uses the baseline model and returns a trained model.
:param model: model
:return: model
"""
# Define the augmentation configuration we will use for training
TRAIN_DATAGEN = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
# Build the train generator
TRAIN_GENERATOR = TRAIN_DATAGEN.flow_from_directory(
TRAIN_PATH,
target_size=(IMG_WIDTH, IMG_HEIGHT),
batch_size=32,
class_mode='categorical')
TEST_DATAGEN = ImageDataGenerator(rescale=1. / 255)
# Build the validation generator
TEST_GENERATOR = TEST_DATAGEN.flow_from_directory(
TEST_PATH,
target_size=(IMG_WIDTH, IMG_HEIGHT),
batch_size=32,
class_mode='categorical')
# Train model
model.fit_generator(
TRAIN_GENERATOR,
samples_per_epoch=NB_TRAIN_SAMPLES,
nb_epoch=NB_EPOCH,
validation_data=TEST_GENERATOR,
nb_val_samples=NB_VALIDATION_SAMPLES)
# Always save your weights after training or during training
model.save_weights('first_try.h5')
# END OF FILE -------------------------------------------------------------------------------------#
and the error:
Using TensorFlow backend.
Training set: 0 files.
Test set: 0 files.
Traceback (most recent call last):
File "/Users/christoshadjinikolis/GitHub_repos/datareplyuk/ODSC_Facial_Sentiment_Analysis/src/model/__init__.py", line 79, in <module>
model = baseline_model()
File "/Users/christoshadjinikolis/GitHub_repos/datareplyuk/ODSC_Facial_Sentiment_Analysis/src/model/training_module.py", line 31, in baseline_model
model.add(Convolution2D(32, 5, 5, border_mode='valid', input_shape=(3, IMG_WIDTH, IMG_HEIGHT)))
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/keras/models.py", line 276, in add
layer.create_input_layer(batch_input_shape, input_dtype)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/keras/engine/topology.py", line 370, in create_input_layer
self(x)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/keras/engine/topology.py", line 514, in __call__
self.add_inbound_node(inbound_layers, node_indices, tensor_indices)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/keras/engine/topology.py", line 572, in add_inbound_node
Node.create_node(self, inbound_layers, node_indices, tensor_indices)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/keras/engine/topology.py", line 149, in create_node
output_tensors = to_list(outbound_layer.call(input_tensors[0], mask=input_masks[0]))
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/keras/layers/convolutional.py", line 466, in call
filter_shape=self.W_shape)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/keras/backend/tensorflow_backend.py", line 1579, in conv2d
x = tf.nn.conv2d(x, kernel, strides, padding=padding)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/tensorflow/python/ops/gen_nn_ops.py", line 394, in conv2d
data_format=data_format, name=name)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/op_def_library.py", line 703, in apply_op
op_def=op_def)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 2319, in create_op
set_shapes_for_outputs(ret)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 1711, in set_shapes_for_outputs
shapes = shape_func(op)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/common_shapes.py", line 246, in conv2d_shape
padding)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/common_shapes.py", line 184, in get2d_conv_output_size
(row_stride, col_stride), padding_type)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/common_shapes.py", line 149, in get_conv_output_size
"Filter: %r Input: %r" % (filter_size, input_size))
ValueError: Filter must not be larger than the input: Filter: (5, 5) Input: (3, 350)
The problem is that the order of input_shape() changes depending the backend you are using (tensorflow or theano).
The best solution I found was defining this order in the file ~/.keras/keras.json.
Try to use the theano order with tensorflow backend, or theano order with theano backend.
Create the keras directory in your home and create the keras json: mkdir ~/.keras && touch ~/.keras/keras.json
{
"image_dim_ordering": "th",
"epsilon": 1e-07,
"floatx": "float32",
"backend": "tensorflow"
}
Just encountered the same problem myself, when I was following a tutorial. As pointed out by #Yao Zhang, the error is caused by the order in the input_shape. There are multiple ways to solve the problem.
Option 1: Change the order in input_shape
The line of your code
model.add(Convolution2D(32, 5, 5, border_mode='valid', input_shape=(3, IMG_WIDTH, IMG_HEIGHT)))
should be changed to
model.add(Convolution2D(32, 5, 5, border_mode='valid', input_shape=(IMG_WIDTH, IMG_HEIGHT, 3)))
which should be fine then.
Option 2: Specify image_dim_ordering in your layers
Option 3: Modify the keras configuration file by changing 'tf' to 'th' in your ~/.keras/keras.json