这是我第一次使用 tensorflow,我遇到了无法解决的问题。 我在 stackoverflow 上发现了很多相同的问题,但它们对我没有帮助。 (可能我只是不知道如何正确使用它) 我有一个模型,由这个算法训练
import seaborn as sns
import matplotlib.pyplot as plt
from tensorflow import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Flatten, Dropout
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras import layers
from sklearn.metrics import classification_report, confusion_matrix
import tensorflow as tf
import cv2
import os
import numpy as np
from resources.Globals import *
labels = ['houses', 'other']
img_size = 400
def get_data(data_dir):
data = []
for label in labels:
path = os.path.join(data_dir, label)
class_num = labels.index(label)
for img in os.listdir(path):
try:
img_arr = cv2.imread(os.path.join(path, img))[..., ::-1] # Convert BGR to RGB format
resized_arr = cv2.resize(img_arr, (img_size, img_size)) # Reshaping images to preferred size
data.append([resized_arr, class_num])
except Exception as e:
print(e)
return np.array(data, dtype="object")
def main():
train = get_data('E:/Projects/Pycharm Projects/sapper/files/Neural_networks/Train')
val = get_data('E:/Projects/Pycharm Projects/sapper/files/Neural_networks/Test')
# Visualize the data
l = []
for i in train:
if i[1] != 0:
l.append("houses")
else:
l.append("other")
sns.set_style('darkgrid')
sns.countplot(l)
# House
plt.figure(figsize=(5, 5))
plt.imshow(train[1][0])
plt.title(labels[train[0][1]])
# Other
plt.figure(figsize=(5, 5))
plt.imshow(train[-1][0])
plt.title(labels[train[-1][1]])
# Data Preprocessing
x_train = []
y_train = []
x_val = []
y_val = []
for feature, label in train:
x_train.append(feature)
y_train.append(label)
for feature, label in val:
x_val.append(feature)
y_val.append(label)
# Normalize the data
x_train = np.array(x_train) / 255
x_val = np.array(x_val) / 255
x_train.reshape(-1, img_size, img_size, 1)
y_train = np.array(y_train)
x_val.reshape(-1, img_size, img_size, 1)
y_val = np.array(y_val)
# Data augmentation
datagen = ImageDataGenerator(
featurewise_center=False, # set input mean to 0 over the dataset
samplewise_center=False, # set each sample mean to 0
featurewise_std_normalization=False, # divide inputs by std of the dataset
samplewise_std_normalization=False, # divide each input by its std
zca_whitening=False, # apply ZCA whitening
rotation_range=30, # randomly rotate images in the range (degrees, 0 to 180)
zoom_range=0.2, # Randomly zoom image
width_shift_range=0.1, # randomly shift images horizontally (fraction of total width)
height_shift_range=0.1, # randomly shift images vertically (fraction of total height)
horizontal_flip=True, # randomly flip images
vertical_flip=False) # randomly flip images
print('Pretrain')
datagen.fit(x_train)
print('After train')
# Define the Model
model = Sequential()
model.add(Conv2D(32, 3, padding="same", activation="relu", input_shape=(img_size, img_size, 3)))
model.add(MaxPool2D())
model.add(Conv2D(64, 3, padding="same", activation="relu"))
model.add(MaxPool2D())
model.add(Dropout(DROPOUT))
model.add(Flatten())
model.add(Dense(128, activation="relu"))
model.add(Dense(2, activation="softmax"))
model.summary()
# Compile the model
opt = keras.optimizers.Adam(lr=0.000001) # Adam as optimizer and SparseCategoricalCrossentropy as the loss function
model.compile(optimizer=opt, loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
print('Pretrain #2')
# Train model
history = model.fit(x_train, y_train, epochs=AMOUNT_OF_EPOCHS, validation_data=(x_val, y_val))
print('After train #2')
model.save("../../files/Neural_networks/model/training_3")
print('Model saved')
# Evaluating the result
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(1, AMOUNT_OF_EPOCHS + 1)
plt.figure(figsize=(15, 15))
plt.subplot(2, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(2, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
# Precision and accuracy report
predictions = model.predict_classes(x_val)
predictions = predictions.reshape(1, -1)[0]
print(classification_report(y_val, predictions, target_names=['Rugby (Class 0)', 'Soccer (Class 1)']))
# Show all plots
plt.show()
if __name__ == '__main__':
main()
我还有代码,应该使用我的模型进行预测
import cv2
import tensorflow as tf
import numpy as np
from keras_preprocessing.image import ImageDataGenerator
CATEGORIES = ['houses', 'other']
def prepare(filepath):
IMG_SIZE = 400 # 50 in txt-based
img_array = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE)
new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
new_array = np.array(new_array) / 255
return new_array.reshape(-1, IMG_SIZE, IMG_SIZE, 1)
model = tf.keras.models.load_model("../../files/Neural_networks/model/training_3")
model.summary()
test = prepare("E:/Projects/Pycharm Projects/sapper/files/Neural_networks/Test/houses/5_frontal.jpg")
pred = test
prediction = model.predict([pred])
print('after predict')
print(prediction) # will be a list in a list.
print(CATEGORIES[int(prediction[0][0])])
在第二个代码中
prediction = model.predict([pred])
我有这个错误:
ValueError:层序的输入 0 与层不兼容:输入形状的预期轴 -1 具有值 3,但接收到形状为 [None, 400, 400, 1] 的输入
整个错误:
Traceback (most recent call last):
File "E:/Projects/Pycharm Projects/sapper/bin/Main/test_2.py", line 25, in <module>
prediction = model.predict([pred])
File "E:\Python versions\Python37\lib\site-packages\tensorflow\python\keras\engine\training.py", line 130, in _method_wrapper
return method(self, *args, **kwargs)
File "E:\Python versions\Python37\lib\site-packages\tensorflow\python\keras\engine\training.py", line 1599, in predict
tmp_batch_outputs = predict_function(iterator)
File "E:\Python versions\Python37\lib\site-packages\tensorflow\python\eager\def_function.py", line 780, in __call__
result = self._call(*args, **kwds)
File "E:\Python versions\Python37\lib\site-packages\tensorflow\python\eager\def_function.py", line 823, in _call
self._initialize(args, kwds, add_initializers_to=initializers)
File "E:\Python versions\Python37\lib\site-packages\tensorflow\python\eager\def_function.py", line 697, in _initialize
*args, **kwds))
File "E:\Python versions\Python37\lib\site-packages\tensorflow\python\eager\function.py", line 2855, in _get_concrete_function_internal_garbage_collected
graph_function, _, _ = self._maybe_define_function(args, kwargs)
File "E:\Python versions\Python37\lib\site-packages\tensorflow\python\eager\function.py", line 3213, in _maybe_define_function
graph_function = self._create_graph_function(args, kwargs)
File "E:\Python versions\Python37\lib\site-packages\tensorflow\python\eager\function.py", line 3075, in _create_graph_function
capture_by_value=self._capture_by_value),
File "E:\Python versions\Python37\lib\site-packages\tensorflow\python\framework\func_graph.py", line 986, in func_graph_from_py_func
func_outputs = python_func(*func_args, **func_kwargs)
File "E:\Python versions\Python37\lib\site-packages\tensorflow\python\eager\def_function.py", line 600, in wrapped_fn
return weak_wrapped_fn().__wrapped__(*args, **kwds)
File "E:\Python versions\Python37\lib\site-packages\tensorflow\python\framework\func_graph.py", line 973, in wrapper
raise e.ag_error_metadata.to_exception(e)
ValueError: in user code:
E:\Python versions\Python37\lib\site-packages\tensorflow\python\keras\engine\training.py:1462 predict_function *
return step_function(self, iterator)
E:\Python versions\Python37\lib\site-packages\tensorflow\python\keras\engine\training.py:1452 step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
E:\Python versions\Python37\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:1211 run
return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
E:\Python versions\Python37\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:2585 call_for_each_replica
return self._call_for_each_replica(fn, args, kwargs)
E:\Python versions\Python37\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:2945 _call_for_each_replica
return fn(*args, **kwargs)
E:\Python versions\Python37\lib\site-packages\tensorflow\python\keras\engine\training.py:1445 run_step **
outputs = model.predict_step(data)
E:\Python versions\Python37\lib\site-packages\tensorflow\python\keras\engine\training.py:1418 predict_step
return self(x, training=False)
E:\Python versions\Python37\lib\site-packages\tensorflow\python\keras\engine\base_layer.py:976 __call__
self.name)
E:\Python versions\Python37\lib\site-packages\tensorflow\python\keras\engine\input_spec.py:216 assert_input_compatibility
' but received input with shape ' + str(shape))
ValueError: Input 0 of layer sequential is incompatible with the layer: expected axis -1 of input shape to have value 3 but received input with shape [None, 400, 400, 1]
我该如何解决?
答案 0 :(得分:1)
你的输入形状显然有问题。
您的模型架构如下。所以输入形状应该是 (1,400,400,3)。
在向网络提供数据的函数 prepare
中,输出形状为 (400,400,1)。这就是为什么您会收到错误消息。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 400, 400, 32) 896
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 200, 200, 32) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 200, 200, 64) 18496
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 100, 100, 64) 0
_________________________________________________________________
dropout (Dropout) (None, 100, 100, 64) 0
_________________________________________________________________
flatten (Flatten) (None, 640000) 0
_________________________________________________________________
dense (Dense) (None, 128) 81920128
_________________________________________________________________
dense_1 (Dense) (None, 2) 258
=================================================================
Total params: 81,939,778
Trainable params: 81,939,778
Non-trainable params: 0
CV2.IMREAD_GRAYSCALE
参数,因为 cv2.imread
不会加载图像的三个 RGB 通道,并且大小仅为 (IMG_SIZE,IMG_SIZE)。
`a = cv2.imread('下载/21.png')
<块引用>a.shape
(652, 1366,3)
<块引用>a = cv2.imread('下载/21.png',cv2.IMREAD_GRAYSCALE)
<块引用>a.shape (652, 1366) `
(1,IMG_SIZE,IMG_SIZE,3)
我尝试在 np.zeros(1,IMG_SIZE,IMG_SIZE,3)
上运行模型,并且运行良好。