我对python和tensorflow还是很陌生,但是已经设法使用自己保存为tf.records的图像数据库来构建,训练和验证CNN。 现在,我希望模型能读取一张图片并进行实时预测。因此,我想通过摆脱解析器(将保存为tf.records的图像解码)解析器来修改验证脚本,并且不批输入图像,因为我只想预测一个。我总是会出现以下错误:
TypeError: Value passed to parameter 'input' has DataType uint8 not in list of allowed values: float16, bfloat16, float32, float64
我仔细查看了用于创建tf.records的脚本,并将它们与我在脚本中用于训练和验证的解析器进行了比较,但找不到错误。
如果您能帮助我发现错误或向我展示一种更简单的方法来预测已经受过训练的CNN的课程,我将非常感激。
import tensorflow as tf
import cv2
num_classes = 2
crop_top = 5
crop_bottom = 10
crop_sides = 5
img_size_height = 80
img_size_width = 100
model_dir = "./2cv_128fc"
def load_image():
img = cv2.imread('./dir_pred_img/img_2.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.resize(img, (img_size_width + (2 * crop_sides), img_size_height + crop_top + crop_bottom),
interpolation=cv2.INTER_CUBIC)
img = img[crop_top:(img_size_height + crop_top), crop_sides:(img_size_width + crop_sides)]
features = {'image': img}
return features
def conv_nn(input_layer):
conv_1 = tf.layers.conv2d(inputs=input_layer, name='conv_layer_1', filters=32, kernel_size=3, padding='same',
activation=tf.nn.relu)
pool_1 = tf.layers.max_pooling2d(inputs=conv_1, pool_size=2, strides=2)
conv_2 = tf.layers.conv2d(inputs=pool_1, name='conv_layer_2', filters=32, kernel_size=3, padding='same',
activation=tf.nn.relu)
pool_2 = tf.layers.max_pooling2d(inputs=conv_2, pool_size=2, strides=2)
flatten = tf.contrib.layers.flatten(pool_2)
fc_layer = tf.layers.dense(inputs=flatten, name='fully_connected_layer', units=128, activation=tf.nn.relu)
fc_layer = tf.layers.dropout(fc_layer, rate=0.5, noise_shape=None, seed=None)
output_layer = tf.layers.dense(inputs=fc_layer, name='output_layer', units=num_classes)
return output_layer
def model_fn(features):
input_layer = features["image"]
input_layer = tf.identity(input_layer, name="input_tensor")
input_layer = tf.reshape(input_layer, [-1, img_size_height, img_size_width, 1]) # 1.tensor 2.shape
input_layer = tf.identity(input_layer, name="input_tensor_reshaped")
logits = conv_nn(input_layer)
pred = tf.nn.softmax(logits=logits)
return pred
model = tf.estimator.Estimator(model_fn=model_fn, model_dir=model_dir)
prediction = list(model.predict(input_fn=load_image))
print(prediction[0])
完整的错误消息:
WARNING:tensorflow:Input graph does not use tf.data.Dataset or contain a QueueRunner. That means predict yields forever. This is probably a mistake.
Traceback (most recent call last):
File "C:/Users/Dell/PycharmProjects/create_data/pred_img.py", line 54, in <module>
prediction = list(model.predict(input_fn=load_image))
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\estimator\estimator.py", line 577, in predict
features, None, model_fn_lib.ModeKeys.PREDICT, self.config)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\estimator\estimator.py", line 1195, in _call_model_fn
model_fn_results = self._model_fn(features=features, **kwargs)
File "C:/Users/Dell/PycharmProjects/create_data/pred_img.py", line 47, in model_fn
logits = conv_nn(input_layer)
File "C:/Users/Dell/PycharmProjects/create_data/pred_img.py", line 27, in conv_nn
activation=tf.nn.relu)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\layers\convolutional.py", line 417, in conv2d
return layer.apply(inputs)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 817, in apply
return self.__call__(inputs, *args, **kwargs)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\layers\base.py", line 374, in __call__
outputs = super(Layer, self).__call__(inputs, *args, **kwargs)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 757, in __call__
outputs = self.call(inputs, *args, **kwargs)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\keras\layers\convolutional.py", line 194, in call
outputs = self._convolution_op(inputs, self.kernel)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\ops\nn_ops.py", line 868, in __call__
return self.conv_op(inp, filter)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\ops\nn_ops.py", line 520, in __call__
return self.call(inp, filter)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\ops\nn_ops.py", line 204, in __call__
name=self.name)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\ops\gen_nn_ops.py", line 1043, in conv2d
data_format=data_format, dilations=dilations, name=name)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 609, in _apply_op_helper
param_name=input_name)
File "C:\Users\Dell\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 60, in _SatisfiesTypeConstraint
", ".join(dtypes.as_dtype(x).name for x in allowed_list)))
TypeError: Value passed to parameter 'input' has DataType uint8 not in list of allowed values: float16, bfloat16, float32, float64
答案 0 :(得分:1)
以下代码描述了如何使用keras来实现。
import keras
from keras.layers import Input, Convolution2D, MaxPooling2D, Cropping2D, Dense, Flatten, Dropout
from keras.preprocessing import image
from keras.models import Model
from keras.optimizers import Adam
import cv2
import numpy as np
# parameters
num_classes = 2
crop_top = 5
crop_bottom = 10
crop_sides = 5
img_size_height = 80
img_size_width = 100
channels = 3
input_shape = (img_size_height, img_size_width, channels)
activation = 'relu'
learning_rate = 0.0001
if num_classes == 2:
loss = 'binary_crossentropy'
else:
loss = 'categorical_crossentropy'
test_image = image.load_img('./data/img.png')
test_image = image.img_to_array(test_image)
input_shape = test_image.shape
def model(input_shape=input_shape):
inputs = Input(shape=input_shape)
# cropping=((pixels_from_top, pixels_from_bottom), (pixels_from_left, pixels_from_right))
cropping = Cropping2D(cropping=((crop_top, crop_bottom), (crop_sides, crop_sides)))(inputs)
conv_1 = Convolution2D(32, kernel_size=(3, 3), padding='same', activation=activation)(cropping)
pool_1 = MaxPooling2D(pool_size=(2, 2), strides=(2, 2))(conv_1)
conv_2 = Convolution2D(32, kernel_size=(3, 3), padding='same', activation=activation)(pool_1)
pool_2 = MaxPooling2D(pool_size=(2, 2), strides=(2, 2))(conv_2)
flatten = Flatten()(pool_2)
dense_1 = Dense(128, activation=activation, name='fully_connected_layer')(flatten)
dropout = Dropout(0.5)(dense_1)
outputs = Dense(num_classes, activation='softmax')(dropout)
model = Model(inputs=inputs, outputs=outputs)
adam = Adam(lr=learning_rate)
model.compile(optimizer=adam, loss=loss, metrics=['acc', 'mse', 'mae'])
model.summary()
return model
test_image = np.expand_dims(test_image, axis=0)
model = model(input_shape)
# note that without training we will only get random results
prediction = model.predict_on_batch(test_image)
print(prediction)
答案 1 :(得分:0)
我找到了解决方案。 我在def load_image()的末尾添加了以下行,并返回了数据集而不是功能。
dataset = tf.data.Dataset.from_tensors(features)
return dataset