Классификация изображений Keras CNN - имя исходного изображения из Dataframe - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть набор данных:

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 предсказывает только один класс. Это из-за того, как я добавляю или храню данные или что-то еще?

Я проверил это решение , но, похоже, не сработало.

Для моего полного кода, вы можете просмотреть HTML-файл моего IPYNB здесь .

Я что-то упустил? Речь идет не только об устранении проблемы, но и о понимании концепции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...