我正在尝试从adrianalbert的GitHub页面(https://github.com/adrianalbert/urban-environments)重建预训练的VGG16模型。但是,该代码似乎是为Keras的旧版本编写的,从而导致很多错误。
当我第一次尝试运行代码时,卷积层出现以下错误:" C:\Users\miker\Anaconda3\lib\site-packages\ipykernel_launcher.py:9: UserWarning: Update your Conv2D call to the Keras 2 API: Conv2D(512, (3, 3), activation="relu", name="conv1_1") "
我根据此建议更改了卷积层的代码,现在出现错误:" TypeError: unsupported operand type(s) for +: 'int' and 'str' "
我知道这意味着代码正在尝试以不兼容的方式组合字符串和整数对象,但是该错误似乎是在Keras函数之一中发生的,我无法弄清楚是什么原因引起的。任何建议都将不胜感激,因为我是深度学习的新手,也不知道我在做什么!
这是代码,大部分代码直接取自adrianalbert:
# Some of the imported functions and modules are from other sections of the code.
from keras.models import Sequential
from keras.layers.core import Flatten, Dense, Dropout
from keras.layers.convolutional import Convolution2D, MaxPooling2D, ZeroPadding2D
from keras.engine import Layer
from keras import backend as K
from keras.optimizers import SGD
from keras.models import Model
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers import Input
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import GlobalMaxPooling2D
from keras.layers import GlobalAveragePooling2D
from keras.preprocessing import image
from keras.utils import layer_utils
from keras.utils.data_utils import get_file
from keras import backend as K
from keras.applications.imagenet_utils import decode_predictions
from keras.applications.imagenet_utils import preprocess_input
from keras_applications.imagenet_utils import _obtain_input_shape
from keras.engine.topology import get_source_inputs
import cv2, numpy as np
import pandas as pd
import h5py
from skimage.io import imread
from skimage.transform import resize, pyramid_reduce
from collections import Counter
def vgg16(n_classes=1000, input_shape=(224,224,3), fcn=False, add_top=True):
model = Sequential()
if fcn:
model.add(ZeroPadding2D((1,1),input_shape=(None,None,input_shape[2])))
else:
model.add(ZeroPadding2D((1,1),input_shape=input_shape))
model.add(Conv2D(512, (3, 3), activation="relu", name="conv1_1"))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(64, (3, 3), activation="relu", name="conv1_2"))
model.add(MaxPooling2D((2,2), strides=(2,2)))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(128, (3, 3), activation="relu", name="conv2_1"))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(128, (3, 3), activation="relu", name="conv2_2"))
model.add(MaxPooling2D((2,2), strides=(2,2)))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(256, (3, 3), activation="relu", name="conv3_1"))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(256, (3, 3), activation="relu", name="conv3_2"))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(256, (3, 3), activation="relu", name="conv3_3"))
model.add(MaxPooling2D((2,2), strides=(2,2)))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3), activation="relu", name="conv4_1"))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3), activation="relu", name="conv4_2"))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3), activation="relu", name="conv4_3"))
model.add(MaxPooling2D((2,2), strides=(2,2)))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3), activation="relu", name="conv5_1"))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3), activation="relu", name="conv5_2"))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3), activation='relu', name="conv5_3"))
model.add(MaxPooling2D((2,2), strides=(2,2)))
if add_top:
if fcn:
model.add(Convolution2D(4096,7,7,activation="relu",name="dense_1"))
model.add(Convolution2D(4096,1,1,activation="relu",name="dense_2"))
model.add(Convolution2D(n_classes,1,1,name="dense8"))
model.add(Softmax4D(axis=1,name="softmax"))
else:
model.add(Flatten())
model.add(Dense(4096, activation='relu', name="dense6"))
model.add(Dropout(0.5))
model.add(Dense(4096, activation='relu', name="dense7"))
model.add(Dropout(0.5))
model.add(Dense(n_classes, activation='softmax', name="dense8"))
return model
class Softmax4D(Layer):
def __init__(self, axis=-1,**kwargs):
self.axis=axis
super(Softmax4D, self).__init__(**kwargs)
def build(self,input_shape):
pass
def call(self, x,mask=None):
e = K.exp(x - K.max(x, axis=self.axis, keepdims=True))
s = K.sum(e, axis=self.axis, keepdims=True)
return e / s
def load_weights_into_model(model, weights_file, \
layers_to_skip=None, transpose_conv=False):
'''
Loads pretrained weights from weights_file in to the structure defined by model. Has simple checks to ensure that weights from file are being loaded to the corresponding layers in the model.
layers_to_skip is a list of either layer indices (ints) or names (strings).
'''
f = h5py.File(weights_file, "r")
if not layers_to_skip:
layers_to_skip = []
N_layers_file = f.attrs['nb_layers'] if 'nb_layers' in f.attrs.keys()\
else len(f.attrs['layer_names'])
N_layers_model= len(model.layers)
layers_to_load = [l.name for k,l in enumerate(model.layers) \
if len(l.get_weights())>0 and l.name not in layers_to_skip and k not in layers_to_skip]
print("Loading %d layers from file into model..."%len(layers_to_load))
l_file = 0
for l_model in layers_to_load:
# go to next layer in file that has weights to load
while True:
g = f['layer_{}'.format(l_file)]
weights=[g['param_{}'.format(p)] \
for p in range(g.attrs['nb_params'])]
l_file += 1
if len(weights)>0:
break
print(model.get_layer(l_model).name),
# transpose convolutional layers saved with a different backend
layer = model.get_layer(l_model)
k = [k for k,l in enumerate(model.layers) if l.name==l_model][0]
if layer.__class__.__name__ in ['Conv2D', 'Convolution2D'] and transpose_conv:
kernel, bias = weights
if kernel.ndim > 2:
kernel = np.transpose(kernel, (2, 3, 1, 0))
else:
print('reshaping ...')
kernel = np.reshape(kernel, layer.get_weights()[0].shape)
print(kernel.shape)
model.layers[k].set_weights([kernel, bias])
else:
model.layers[k].set_weights(weights)
print("done.")
f.close()
return model
def load_and_preprocess(filename, new_shape=None, channels="RGB",
downsample=None, crop=None):
'''
Load image and do basic preprocessing.
- resize image to a specified shape;
- subtract ImageNet mean;
- make sure output image data is 0...255 uint8.
'''
img = imread(filename) # RGB image
if downsample is not None:
img = pyramid_reduce(img)
if img.max()<=1.0:
img = img * 255.0 / img.max()
if crop is not None:
i = np.random.randint(crop/2, img.shape[0]-crop/2)
j = np.random.randint(crop/2, img.shape[1]-crop/2)
img = img[(i-crop/2):(i+crop/2),(j-crop/2):(j+crop/2)]
if new_shape is not None:
img = resize(img, new_shape, preserve_range=True)
# imagenet_mean_bgr = np.array([103.939, 116.779, 123.68])
imagenet_mean_rgb = np.array([123.68, 116.779, 103.939])
for i in range(3):
img[:,:,i] = img[:,:,i] - imagenet_mean_rgb[i]
# for VGG networks pre-trained on ImageNet, channels are BGR
# (ports from Caffe)
if channels=="BGR":
img = img[:, :, [2,1,0]] # swap channel from RGB to BGR
return img.astype(np.uint8)
def balanced_df(df, nrows=None, k=1, class_column="class"):
cnts = df[class_column].value_counts()
min_cnt = cnts.min()
ret = []
for c in cnts.index:
ret.append(df[df[class_column]==c].sample(min([cnts[c],k*min_cnt])))
ret = pd.concat(ret)
if nrows is not None:
if len(ret) < nrows:
weights = 1.0 / (df[class_column].value_counts() + 1)
weights = {i:w for i,w in zip(weights.index, weights.values)}
weights = df[class_column].apply(lambda x: weights[x])
ret = pd.concat([ret, df.sample(nrows-len(ret), weights=weights)])
else:
ret = ret.sample(nrows)
return ret
def get_class_weights(y):
counter = Counter(y)
majority = max(counter.values())
return {cls: float(majority)/count for cls, count in counter.items()}
def generator_from_df(df, image_generator=None, balance=None, \
class_column="class", filename_column="filename",
batch_size=32, seed=None, new_img_shape=None, \
class_dict=None, shuffle=True, channels="RGB",
downsample=None, crop=None):
idx = 0
if class_dict is None:
myclasses = df[class_column].unique()
myclasses.sort()
class_dict = {c:i for i,c in enumerate(myclasses)}
ok = True
while ok:
if shuffle:
if balance is not None:
df_bal = balanced_df(df, k=balance, nrows=batch_size,
class_column=class_column)
else:
df_bal = df
df_batch = df_bal.sample(batch_size, random_state=seed)
else:
df_batch = df.iloc[idx:(idx+batch_size)]
print("Reading ids %d -- %d"%(idx, idx+batch_size))
if idx + batch_size >= len(df):
print("should stop now!")
ok = False
idx += batch_size
y = []
X = []
for i,r in df_batch.iterrows():
img = load_and_preprocess(r[filename_column],
new_shape=new_img_shape, crop=crop,
channels=channels, downsample=downsample)
X.append(img)
y.append(class_dict[r[class_column]])
X = np.array(X)
y = np.array(y)
yoh = np.zeros((len(y), len(class_dict)))
yoh[np.arange(len(y)), y] = 1
if image_generator is not None:
for X_batch, y_batch in image_generator.flow(X, yoh, batch_size=batch_size, shuffle=shuffle):
break
else:
X_batch, y_batch = X, yoh
yield (X_batch, y_batch)
def generator_from_file(filename, image_generator=None, balance=None, \
batch_size=32, seed=None, new_img_shape=None, \
class_dict=None, shuffle=True, channels="RGB",
downsample=False, crop=None):
df = pd.read_csv(filename)
return generator_from_df(df,
image_generator=image_generator,
balance=balance,
batch_size=batch_size,
seed=seed,
crop=crop,
new_img_shape=new_img_shape,
class_dict=class_dict,
shuffle=shuffle,
channels=channels)
当我运行以下行时会发生错误:
model = vgg16('vgg16_weights.h5')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-9-f62a37630a68> in <module>
----> 1 model = vgg16('vgg16_weights.h5')
<ipython-input-8-59ef76627dbc> in vgg16(n_classes, input_shape, fcn, add_top)
54 model.add(Dense(4096, activation='relu', name="dense7"))
55 model.add(Dropout(0.5))
---> 56 model.add(Dense(n_classes, activation='softmax', name="dense8"))
57
58 return model
~\Anaconda3\lib\site-packages\keras\engine\sequential.py in add(self, layer)
179 self.inputs = network.get_source_inputs(self.outputs[0])
180 elif self.outputs:
--> 181 output_tensor = layer(self.outputs[0])
182 if isinstance(output_tensor, list):
183 raise TypeError('All layers in a Sequential model '
~\Anaconda3\lib\site-packages\keras\engine\base_layer.py in __call__(self, inputs, **kwargs)
429 'You can build it manually via: '
430 '`layer.build(batch_input_shape)`')
--> 431 self.build(unpack_singleton(input_shapes))
432 self.built = True
433
~\Anaconda3\lib\site-packages\keras\layers\core.py in build(self, input_shape)
864 name='kernel',
865 regularizer=self.kernel_regularizer,
--> 866 constraint=self.kernel_constraint)
867 if self.use_bias:
868 self.bias = self.add_weight(shape=(self.units,),
~\Anaconda3\lib\site-packages\keras\legacy\interfaces.py in wrapper(*args, **kwargs)
89 warnings.warn('Update your `' + object_name + '` call to the ' +
90 'Keras 2 API: ' + signature, stacklevel=2)
---> 91 return func(*args, **kwargs)
92 wrapper._original_function = func
93 return wrapper
~\Anaconda3\lib\site-packages\keras\engine\base_layer.py in add_weight(self, name, shape, dtype, initializer, regularizer, trainable, constraint)
247 if dtype is None:
248 dtype = K.floatx()
--> 249 weight = K.variable(initializer(shape),
250 dtype=dtype,
251 name=name,
~\Anaconda3\lib\site-packages\keras\initializers.py in __call__(self, shape, dtype)
207 scale /= max(1., fan_out)
208 else:
--> 209 scale /= max(1., float(fan_in + fan_out) / 2)
210 if self.distribution == 'normal':
211 # 0.879... = scipy.stats.truncnorm.std(a=-2, b=2, loc=0., scale=1.)
TypeError: unsupported operand type(s) for +: 'int' and 'str'
答案 0 :(得分:0)
这是您的电话:
model = vgg16('vgg16_weights.h5')
这是vgg16
函数的定义:
def vgg16(n_classes=1000, input_shape=(224,224,3), fcn=False, add_top=True):
因此,您要传递字符串('vgg16_weights.h5'
作为vgg16
函数的第一个参数,而该第一个参数实际上是类的数目。这就是为什么会出错的原因,因为类的数目是一个字符串。