我在使用Keras构建这个自编码器时遇到了问题。输入的形状取决于屏幕大小,输出将是下一个屏幕大小的预测… 然而似乎有一个我无法解决的错误… 请原谅我在这个网站上的糟糕格式…
代码:
def model_build():input_img = InputLayer(shape=(1, env_size()[1], env_size()[0]))x = Conv2D(32, (3, 3), activation='relu', padding='same')(input_img)x = MaxPooling2D((2, 2), padding='same')(x)x = Conv2D(16, (3, 3), activation='relu', padding='same')(x)x = MaxPooling2D((2, 2), padding='same')(x)x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)encoded = MaxPooling2D((2, 2), padding='same')(x)x = Conv2D(8, (3, 3), activation='relu', padding='same')(encoded)x = UpSampling2D((2, 2))(x)x = Conv2D(16, (3, 3), activation='relu', padding='same')(x)x = UpSampling2D((2, 2))(x)x = Conv2D(32, (3, 3), activation='relu')(x)x = UpSampling2D((2, 2))(x)decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)model = Model(input_img, decoded)return modelif __name__ == '__main__': model = model_build() model.compile('adam', 'mean_squared_error') y = np.array([env()]) print(y.shape) print(y.ndim) debug = model.fit(np.array([[env()]]), np.array([[env()]]))
错误:
Traceback (most recent call last): File “/home/ai/Desktop/algernon-test/rewarders.py”, line 46, in debug = model.fit(np.array([[env()]]), np.array([[env()]])) File “/home/ai/.local/lib/python3.6/site-packages/keras/engine/training.py”, line 952, in fit batch_size=batch_size) File “/home/ai/.local/lib/python3.6/site-packages/keras/engine/training.py”, line 789, in _standardize_user_data exception_prefix=’target’) File “/home/ai/.local/lib/python3.6/site-packages/keras/engine/training_utils.py”, line 138, in standardize_input_data str(data_shape)) ValueError: Error when checking target: expected conv2d_7 to have shape (4, 268, 1) but got array with shape (1, 270, 480)
编辑:
导入为env()的get_screen的代码:
def get_screen(): img = screen.grab() img = img.resize(screen_size()) img = img.convert('L') img = np.array(img) return img
回答:
看起来env_size()
和env()
以某种方式弄乱了图像尺寸。考虑这个例子:
image1 = np.random.rand(1, 1, 270, 480) #第一个维度是批量大小,用于测试目的image2 = np.random.rand(1, 4, 268, 1) #或者任何其他任意维度input_img = layers.Input(shape=image1[0].shape)x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(input_img)x = layers.MaxPooling2D((2, 2), padding='same')(x)x = layers.Conv2D(16, (3, 3), activation='relu', padding='same')(x)x = layers.MaxPooling2D((2, 2), padding='same')(x)x = layers.Conv2D(8, (3, 3), activation='relu', padding='same')(x)encoded = layers.MaxPooling2D((2, 2), padding='same')(x)x = layers.Conv2D(8, (3, 3), activation='relu', padding='same')(encoded)x = layers.UpSampling2D((2, 2))(x)x = layers.Conv2D(16, (3, 3), activation='relu', padding='same')(x)x = layers.UpSampling2D((2, 2))(x)x = layers.Conv2D(32, (3, 3), activation='relu')(x)x = layers.UpSampling2D((2, 2))(x)decoded = layers.Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)model = tf.keras.Model(input_img, decoded)model.compile('adam', 'mean_squared_error')model.summary()
这行代码会工作:
model.fit(image1, nb_epoch=1, batch_size=1)
但这行不行:
model.fit(image2, nb_epoch=1, batch_size=1)
编辑:为了使输出的尺寸与输入相同,你需要仔细计算卷积核的大小。image1 = np.random.rand(1, 1920, 1080, 1)
input_img = layers.Input(shape=image1[0].shape)x = layers.Conv2D(32, 3, activation='relu', padding='same')(input_img)x = layers.MaxPooling2D((2, 2), padding='same')(x)x = layers.Conv2D(16, 3, activation='relu', padding='same')(x)x = layers.MaxPooling2D((2, 2), padding='same')(x)x = layers.Conv2D(8, 3, activation='relu', padding='same')(x)encoded = layers.MaxPooling2D((2, 2), padding='same')(x)x = layers.Conv2D(8, 3, activation='relu', padding='same')(encoded)x = layers.UpSampling2D((2, 2))(x)x = layers.Conv2D(16, 3, activation='relu', padding='same')(x)x = layers.UpSampling2D((2, 2))(x)x = layers.Conv2D(32, 1, activation='relu')(x) #例如,将核大小设置为1x = layers.UpSampling2D((2, 2))(x)decoded = layers.Conv2D(1, 3, activation='sigmoid', padding='same')(x)model = tf.keras.Model(input_img, decoded)model.compile('adam', 'mean_squared_error')model.summary()
这将输出相同的尺寸。
根据这个指南 http://cs231n.github.io/convolutional-networks/
我们可以根据输入体积大小(W),卷积层神经元的感受野大小(F),应用它们的步长(S),以及在边界上使用的零填充量(P)来计算输出体积的空间大小。你可以说服自己,计算“适合”的神经元数量的正确公式为(W−F+2P)/S+1。例如,对于7×7的输入和3×3的滤波器,步长为1,填充为0,我们将得到5×5的输出。如果步长为2,我们将得到3×3的输出。