这是我拥有的数据集:
imageName image_class
1466021829460.jpg 1
1466022672915.jpg 6
1466025877175.jpg 1
1466023217363.jpg 1
1466026546959.jpg 0
因此,我不得不从链接中抓取这些图像,并将其存储在文件夹中。我用于抓取的代码是这样的(使用urllib
模块):
import urllib.request
for i in df['imageName']:
urllib.request.urlretrieve('https://*********/*****/*****/****/' + str(i),i)
print ("Image saved")
现在,我使用以下代码在像素数组后面附加类:
def proc_images():
x = [] # images as arrays
y = [] # labels
WIDTH = 128
HEIGHT = 128
findings = df['image_class'].values
for img,finding in zip(images,findings):
base = os.path.basename(img)
full_size_image = cv2.imread(img)
# Read and resize image
y.append(finding)
x.append(cv2.resize(full_size_image, (WIDTH,HEIGHT), interpolation=cv2.INTER_CUBIC))
return x,y
X,y = proc_images()
df1 = pd.DataFrame()
df1["images"]=X
df1["labels"]=y
print(len(df1), df1.images[0].shape)
print(type(X))
输出:
5000 (128, 128, 3)
<class 'list'>
现在的数据框:
images labels
0 [[[18, 47, 74], [25, 55, 82], [28, 58, 87], [3... 1
1 [[[162, 158, 100], [164, 161, 103], [166, 159,... 6
2 [[[12, 5, 43], [15, 9, 30], [25, 18, 28], [14,... 1
3 [[[107, 159, 191], [116, 163, 197], [110, 153,... 1
5 [[[143, 147, 142], [145, 149, 144], [143, 147,... 4
下一步:
X=np.array(X)
X=X/255.0
X_train, X_test, Y_train, Y_test = train_test_split(X, y, test_size=0.2)
print("Training Data Shape:", X_train.shape)
print("Testing Data Shape:", X_test.shape)
print("Training Data Shape:", len(X_train), X_train[0].shape)
print("Testing Data Shape:", len(X_test), X_test[0].shape)
输出:
Training Data Shape: (2837, 128, 128, 3)
Testing Data Shape: (710, 128, 128, 3)
Training Data Shape: 2837 (128, 128, 3)
Testing Data Shape: 710 (128, 128, 3)
Y_trainHot = to_categorical(Y_train, num_classes = 7)
Y_testHot = to_categorical(Y_test, num_classes = 7)
主要型号:
from keras.applications.vgg16 import VGG16
from keras.models import Model
#weight_path = '../input/keras-pretrained-models/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5'
im_size = 128
map_characters=dict_characters
def vgg16network(a,b,c,d,e,f,g):
num_class = f
epochs = g
base_model = VGG16(weights='imagenet', include_top=False, input_shape=(im_size, im_size, 3))
# Add a new top layer
x = base_model.output
x = Flatten()(x)
predictions = Dense(num_class, activation='softmax')(x)
# This is the model we will train
model = Model(inputs=base_model.input, outputs=predictions)
# First: train only the top layers (which were randomly initialized)
for layer in base_model.layers:
layer.trainable = False
model.compile(loss='categorical_crossentropy',
optimizer=keras.optimizers.RMSprop(lr=0.0001),
metrics=['accuracy'])
callbacks_list = [keras.callbacks.EarlyStopping(monitor='val_acc', patience=3, verbose=1)]
model.summary()
model.fit(a,b, epochs=epochs, class_weight=e, validation_data=(c,d), verbose=1,callbacks = [MetricsCheckpoint('logs')])
score = model.evaluate(c,d, verbose=0)
print('\nKeras CNN #2 - accuracy:', score[1], '\n')
y_pred = model.predict(c)
print('\n', sklearn.metrics.classification_report(np.where(d > 0)[1], np.argmax(y_pred, axis=1), target_names=list(map_characters.values())), sep='')
Y_pred_classes = np.argmax(y_pred,axis = 1)
Y_true = np.argmax(d,axis = 1)
confusion_mtx = confusion_matrix(Y_true, Y_pred_classes)
plotKerasLearningCurve()
plt.show()
plot_confusion_matrix(confusion_mtx, classes = list(map_characters.values()))
plt.show()
return model
然后进行一些采样,因为数据集不平衡:
from imblearn.over_sampling import RandomOverSampler
ros = RandomOverSampler(ratio='auto')
X_trainRos, Y_trainRos = ros.fit_sample(X_trainFlat, Y_train)
X_testRos, Y_testRos = ros.fit_sample(X_testFlat, Y_test)
# Encode labels to hot vectors (ex : 2 -> [0,0,1,0,0,0,0,0,0,0])
Y_trainRosHot = to_categorical(Y_trainRos, num_classes = 7)
Y_testRosHot = to_categorical(Y_testRos, num_classes = 7)
print("X_train: ", X_train.shape)
print("X_trainFlat: ", X_trainFlat.shape)
print("X_trainRos Shape: ",X_trainRos.shape)
print("X_testRos Shape: ",X_testRos.shape)
print("Y_trainRosHot Shape: ",Y_trainRosHot.shape)
print("Y_testRosHot Shape: ",Y_testRosHot.shape)
然后我想看一下形状:
for i in range(len(X_trainRos)):
height, width, channels = 128,128,3
X_trainRosReshaped = X_trainRos.reshape(len(X_trainRos),height,width,channels)
print("X_trainRos Shape: ",X_trainRos.shape)
print("X_trainRosReshaped Shape: ",X_trainRosReshaped.shape)
for i in range(len(X_testRos)):
height, width, channels = 128,128,3
X_testRosReshaped = X_testRos.reshape(len(X_testRos),height,width,channels)
print("X_testRos Shape: ",X_testRos.shape)
print("X_testRosReshaped Shape: ",X_testRosReshaped.shape)
输出:
X_trainRos Shape: (7806, 49152)
X_trainRosReshaped Shape: (7806, 128, 128, 3)
X_testRos Shape: (2028, 49152)
X_testRosReshaped Shape: (2028, 128, 128, 3)
运行功能:
vgg16network(X_trainRosReshaped, Y_trainRosHot, X_testRosReshaped, Y_testRosHot,class_weight,7,25)
在3个或4个时期之后,我的acc
增加了,但val_acc
却被卡住了。
Epoch 1/25
7806/7806 [==============================] - 2089s 268ms/step - loss: 1.7347 - acc: 0.2848 - val_loss: 1.8463 - val_acc: 0.1583
Epoch 2/25
7806/7806 [==============================] - 1995s 256ms/step - loss: 1.4878 - acc: 0.4813 - val_loss: 1.8764 - val_acc: 0.1558
所有图像都被抓取并存储在一个文件夹中,我在像素上附加了类标签。我不知道为什么,但是我也早些时候面对过这个问题。每当我在图像像素上附加类别标签并形成数据框时,keras只会预测一个类别。是因为我添加或存储数据的方式,还是其他原因?
我检查了this solution,但似乎没有解决问题。
有关我的完整代码,您可以查看HTML file of my IPYNB here。
我想念一些概念吗?这不仅是解决问题,还在于理解概念。