我试图从头开始训练我的VGG16网络。为此,我从https://gist.github.com/baraldilorenzo/07d7802847aaad0a35d3
下载了该体系结构其中一位作者将代码编写为vgg-16_keras.py代码。在此代码中,预期的默认图像尺寸为224x224。我输入的图像也具有相同的尺寸。因此,大小没有问题。
接下来,我做了一些细微的更改,以使体系结构准备好在手边的一些示例图像上训练模型。尝试训练模型时,出现“负尺寸”错误。为了调试代码,我试图获得一些功能,该功能可以为我提供不同层的输出尺寸,但不幸的是,没有。
我正在发布我的代码以及错误消息
import keras
import numpy as np
from keras import backend as K
from keras.models import Sequential
from keras.layers import Activation, ZeroPadding2D, Convolution2D, MaxPooling2D, Dropout
from keras.layers.core import Dense, Flatten
from keras.optimizers import Adam
from keras.metrics import categorical_crossentropy
from keras.preprocessing.image import ImageDataGenerator
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import *
from matplotlib import pyplot as plt
from sklearn.metrics import confusion_matrix
import itertools
from matplotlib.pyplot import *
train_path="cats-and-dogs/train"
valid_path="cats-and-dogs/valid"
test_path="cats-and-dogs/test"
train_batches=ImageDataGenerator().flow_from_directory(train_path, target_size=(224,224), classes=['dog','cat'], batch_size=20)
valid_batches=ImageDataGenerator().flow_from_directory(valid_path, target_size=(224,224), classes=['dog','cat'], batch_size=10)
test_batches=ImageDataGenerator().flow_from_directory(test_path, target_size=(224,224), classes=['dog','cat'], batch_size=10)
imgs,labels=next(train_batches)
#Defining individual layers for oour CNN
l1=ZeroPadding2D((1,1),input_shape=(3,224,224))
l2=Convolution2D(64, 3, activation='relu')
l3=ZeroPadding2D((1,1))
l4=Convolution2D(64, 3, activation='relu')
l5=MaxPooling2D((2,2), strides=(2,2))
#
#
l6=ZeroPadding2D((1,1))
l7=Convolution2D(128, 3, activation='relu')
l8=ZeroPadding2D((1,1))
l9=Convolution2D(128, 3, activation='relu')
l10=MaxPooling2D((2,2), strides=(2,2))
l11=ZeroPadding2D((1,1))
l12=Convolution2D(256, 3, 3, activation='relu')
l13=ZeroPadding2D((1,1))
l14=Convolution2D(256, 3, 3, activation='relu')
l15=ZeroPadding2D((1,1))
l16=Convolution2D(256, 3, 3, activation='relu')
l17=MaxPooling2D((2,2), strides=(2,2))
l18=ZeroPadding2D((1,1))
l19=Convolution2D(512, 3, 3, activation='relu')
l20=ZeroPadding2D((1,1))
l21=Convolution2D(512, 3, 3, activation='relu')
l22=ZeroPadding2D((1,1))
l23=Convolution2D(512, 3, 3, activation='relu')
l24=MaxPooling2D((2,2), strides=(2,2))
l25=ZeroPadding2D((1,1))
l26=Convolution2D(512, 3, 3, activation='relu')
l27=ZeroPadding2D((1,1))
l28=Convolution2D(512, 3, 3, activation='relu')
l29=ZeroPadding2D((1,1))
l30=Convolution2D(512, 3, 3, activation='relu')
l31=MaxPooling2D((2,2), strides=(2,2))
l32=Flatten()
l33=Dense(4096, activation='relu')
l34=Dropout(0.5)
l35=Dense(4096, activation='relu')
l36=Dropout(0.5)
l37=Dense(1000, activation='softmax')
model = Sequential([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12,l13,l14,l15,l16,l17,l18,l19,l20,l21,l22,l23,l24,l25,l26,l27,l28,l29,l30,l31,l32,l33,l34,l35,l36,l37])
#model = Sequential([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10])
#model = Sequential([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10])
print("Now Printing the model summary \n")
print(model.summary())
请注意,我没有对代码中给出的尺寸(超参数值)进行任何更改。我只是从文档角度修改了代码,例如命名不同的图层,添加注释等。
此外,我还建议自己诊断此类错误的方法。
错误消息如下:
runfile('/home/upendra/vgg_from_scratch', wdir='/home/upendra') Found 200 images belonging to 2 classes. Found 100 images belonging to 2 classes. Found 60 images belonging to 2 classes. /home/upendra/vgg_from_scratch:53: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (3, 3), activation="relu")` l12=Convolution2D(256, 3, 3, activation='relu') /home/upendra/vgg_from_scratch:55: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (3, 3), activation="relu")` l14=Convolution2D(256, 3, 3, activation='relu') /home/upendra/vgg_from_scratch:57: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (3, 3), activation="relu")` l16=Convolution2D(256, 3, 3, activation='relu') /home/upendra/vgg_from_scratch:61: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(512, (3, 3), activation="relu")` l19=Convolution2D(512, 3, 3, activation='relu') /home/upendra/vgg_from_scratch:63: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(512, (3, 3), activation="relu")` l21=Convolution2D(512, 3, 3, activation='relu') /home/upendra/vgg_from_scratch:65: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(512, (3, 3), activation="relu")` l23=Convolution2D(512, 3, 3, activation='relu') /home/upendra/vgg_from_scratch:69: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(512, (3, 3), activation="relu")` l26=Convolution2D(512, 3, 3, activation='relu') /home/upendra/vgg_from_scratch:71: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(512, (3, 3), activation="relu")` l28=Convolution2D(512, 3, 3, activation='relu') /home/upendra/vgg_from_scratch:73: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(512, (3, 3), activation="relu")` l30=Convolution2D(512, 3, 3, activation='relu') Traceback (most recent call last):
File "<ipython-input-4-56412ac381d0>", line 1, in <module>
runfile('/home/upendra/vgg_from_scratch', wdir='/home/upendra')
File "/home/upendra/anaconda3/lib/python3.6/site-packages/spyder_kernels/customize/spydercustomize.py", line 668, in runfile
execfile(filename, namespace)
File "/home/upendra/anaconda3/lib/python3.6/site-packages/spyder_kernels/customize/spydercustomize.py", line 108, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "/home/upendra/vgg_from_scratch", line 83, in <module>
model = Sequential([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12,l13,l14,l15,l16,l17,l18,l19,l20,l21,l22,l23,l24,l25,l26,l27,l28,l29,l30,l31,l32,l33,l34,l35,l36,l37])
File "/home/upendra/anaconda3/lib/python3.6/site-packages/keras/engine/sequential.py", line 92, in __init__
self.add(layer)
File "/home/upendra/anaconda3/lib/python3.6/site-packages/keras/engine/sequential.py", line 185, in add
output_tensor = layer(self.outputs[0])
File "/home/upendra/anaconda3/lib/python3.6/site-packages/keras/engine/base_layer.py", line 457, in __call__
output = self.call(inputs, **kwargs)
File "/home/upendra/anaconda3/lib/python3.6/site-packages/keras/layers/pooling.py", line 157, in call
data_format=self.data_format)
File "/home/upendra/anaconda3/lib/python3.6/site-packages/keras/layers/pooling.py", line 220, in _pooling_function
pool_mode='max')
File "/home/upendra/anaconda3/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py", line 3880, in pool2d
data_format=tf_data_format)
File "/home/upendra/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/nn_ops.py", line 2153, in max_pool
name=name)
File "/home/upendra/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/gen_nn_ops.py", line 4640, in max_pool
data_format=data_format, name=name)
File "/home/upendra/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py", line 787, in _apply_op_helper
op_def=op_def)
File "/home/upendra/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 3414, in create_op
op_def=op_def)
File "/home/upendra/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 1756, in __init__
control_input_ops)
File "/home/upendra/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 1592, in _create_c_op
raise ValueError(str(e))
ValueError: Negative dimension size caused by subtracting 2 from 1 for 'max_pooling2d_9/MaxPool' (op: 'MaxPool') with input shapes: [?,1,112,128].
答案 0 :(得分:0)
我怀疑您的Conv2D定义有误。
您有这样的地方:
Convolution2D(512, 3, 3, activation='relu')
我想你是说这个意思
Convolution2D(512, (3, 3), activation='relu')
您可能应该避免使用位置参数以避免混淆,您的位置参数暗示了这一点:
Convolution2D(filters=512, kernel_size=3, strides=3, activation='relu')
我不记得VGG16的步幅为(3, 3)
,这是您所定义的。如果我错了,请纠正我,我将进行更新(我的头上没有烧毁VGG架构)。
请注意,您在max_pooling2d_9/MaxPool
之前的输出形状为[?,1,112,128]
,应参考此行l10=MaxPooling2D((2,2), strides=(2,2))
,因为l9
是最大池之前输出的唯一图层128个功能。但是您应该在所有图层中添加name='a_useful_name'
以便于调试。 max_pooling2d_9/MaxPool
非常难以追踪。
该形状[?,1,112,128]
表示:
?
-未指定批次尺寸1
-第l10
层的图像高度(这是输出l9
,我们希望它与第三个值112
相同),因此这是有问题的孩子。112
-l10
层的图像宽度(看起来正确)128
-输入到最大池层的过滤器(也称为通道)的数量。如果我没有碰到头,希望我能给您足够的洞察力,以了解模型架构以及可以期待的内容以及在哪里寻找帮助您的模型。
一个好的故障排除步骤是使用l6
作为输出层创建模型,而不运行fit
,而是运行predict
来检查该层的输出是否为形状你期望的。重复l7
,l8
等。很快,您会看到意外的输出形状。