Почему это менее точно при применении vggnet? - PullRequest
0 голосов
/ 30 апреля 2018

Я заинтересован в CNN. Итак, я хочу использовать VGGnet в моем коде. Точность лишь немного увеличивается при тренировках. И когда я применил простую CNN без применения vggnet, точность составила 82%. Но когда я применяю vggnet, точность падает до 74%. Я не могу понять, почему используется лучший алгоритм и точность снижается. Что я делаю неправильно? Подходит ли vggnet для моих данных? Как я могу решить эту проблему? Мой набор данных - медицинское изображение (прогнозирование IDC или не IDC) Вот мой код. Буду признателен за ваш добрый совет.


import pandas as pd
import numpy as np
import os
from glob import glob
import itertools

import fnmatch
import random
import matplotlib.pylab as plt
import seaborn as sns
import cv2
from scipy.misc import imresize, imread
import sklearn
from sklearn import model_selection
from sklearn.model_selection import train_test_split, KFold, cross_val_score, StratifiedKFold, learning_curve, GridSearchCV
from sklearn.metrics import confusion_matrix, make_scorer, accuracy_score
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC, LinearSVC
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
import keras
from keras import backend as K
from keras.callbacks import Callback, EarlyStopping, ReduceLROnPlateau, ModelCheckpoint
from keras.preprocessing.image import ImageDataGenerator
from keras.utils.np_utils import to_categorical
from keras.models import Sequential, model_from_json
from keras.optimizers import SGD, RMSprop, Adam, Adagrad, Adadelta
from keras.layers import Dense, Dropout, Activation, Flatten, BatchNormalization, Conv2D, MaxPool2D, MaxPooling2D
%matplotlib inline

imagePatches = glob('../daeun/kaggle/input/IDC_regular_ps50_idx5/**/*.png', recursive=True)

image_name = "../work/kaggle/input/IDC_regular_ps50_idx5/9135/1/9135_idx5_x1701_y1851_class1.png" #Image to be used as query

patternZero = '*class0.png'
patternOne = '*class1.png'

classZero = fnmatch.filter(imagePatches, patternZero)
classOne = fnmatch.filter(imagePatches, patternOne)

print("IDC(-)\n\n",classZero[0:5],'\n')
print("IDC(+)\n\n",classOne[0:5])

def proc_images(lowerIndex,upperIndex):
    x = []
    y = []
    WIDTH = 50
    HEIGHT = 50
    for img in imagePatches[lowerIndex:upperIndex]:
        full_size_image = cv2.imread(img) 
        x.append(cv2.resize(full_size_image, (WIDTH,HEIGHT), interpolation=cv2.INTER_CUBIC))
        if img in classZero:
            y.append(0)
        elif img in classOne:
            y.append(1)
        else:
            return
    return x,y

X,Y = proc_images(0,90000)
df = pd.DataFrame()
df["images"]=X
df["labels"]=Y
X2=df["images"]
Y2=df["labels"]
X2=np.array(X2)
imgs0=[]
imgs1=[]
imgs0 = X2[Y2==0] # (0 = no IDC, 1 = IDC)
imgs1 = X2[Y2==1]

dict_characters = {0: 'IDC(-)', 1: 'IDC(+)'}

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)

X_train = X_train[0:300000] 
Y_train = Y_train[0:300000]
X_test = X_test[0:300000] 
Y_test = Y_test[0:300000]

Y_trainHot = to_categorical(Y_train, num_classes = 2)
Y_testHot = to_categorical(Y_test, num_classes = 2)

lab = df['labels']
dist = lab.value_counts()
sns.countplot(lab)
print(dict_characters)

X_trainShape = X_train.shape[1]*X_train.shape[2]*X_train.shape[3]
X_testShape = X_test.shape[1]*X_test.shape[2]*X_test.shape[3]
X_trainFlat = X_train.reshape(X_train.shape[0], X_trainShape)
X_testFlat = X_test.reshape(X_test.shape[0], X_testShape)

from imblearn.over_sampling import RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler
ros = RandomUnderSampler(ratio='auto')
X_trainRos, Y_trainRos = ros.fit_sample(X_trainFlat, Y_train)
X_testRos, Y_testRos = ros.fit_sample(X_testFlat, Y_test)

Y_trainRosHot = to_categorical(Y_trainRos, num_classes = 2)
Y_testRosHot = to_categorical(Y_testRos, num_classes = 2)

for i in range(len(X_trainRos)):
    height, width, channels = 50,50,3
    X_trainRosReshaped = X_trainRos.reshape(len(X_trainRos),height,width,channels)

for i in range(len(X_testRos)):
    height, width, channels = 50,50,3
    X_testRosReshaped = X_testRos.reshape(len(X_testRos),height,width,channels)

dfRos = pd.DataFrame()
dfRos["labels"]=Y_trainRos
labRos = dfRos['labels']
distRos = lab.value_counts()
sns.countplot(labRos)
print(dict_characters)

def runKerasCNNAugment(a,b,c,d,e,f):
    batch_size = 128
    num_classes = 2
    epochs = 8
    img_rows,img_cols=50,50
    input_shape = (img_rows, img_cols, 3)
    base_model = VGG19(weights = 'imagenet', include_top=False, input_shape=(img_rows, img_cols, 3))
    xx = base_model.output
    xx = Flatten()(xx)
    predictions = Dense(num_classes, activation='softmax')(xx)
    model = Model(inputs=base_model.input, outputs=predictions)
    for layer in base_model.layers:
        layer.trainable = False
    model.compile(loss=keras.losses.categorical_crossentropy,
                  optimizer='adam',
                  metrics=['accuracy'])
    callbacks_list = [keras.callbacks.EarlyStopping(monitor='val_acc', patience=3, verbose=1)]
    datagen = ImageDataGenerator(
        featurewise_center=False,  # set input mean to 0 over the dataset
        samplewise_center=False,  # set each sample mean to 0
        featurewise_std_normalization=False,  # divide inputs by std of the dataset
        samplewise_std_normalization=False,  # divide each input by its std
        zca_whitening=False,  # apply ZCA whitening
        rotation_range=20,  # randomly rotate images in the range (degrees, 0 to 180)
        width_shift_range=0.2,  # randomly shift images horizontally (fraction of total width)
        height_shift_range=0.2,  # randomly shift images vertically (fraction of total height)
        horizontal_flip=True,  # randomly flip images
        vertical_flip=True)  # randomly flip images
    history = model.fit_generator(datagen.flow(a,b, batch_size=32),
                        steps_per_epoch=len(a) / 32, epochs=epochs,class_weight=f, validation_data = [c, d],callbacks = [MetricsCheckpoint('logs')])
    score = model.evaluate(c,d, verbose=0)
    print('\nKeras CNN #1C - accuracy:', score[1],'\n')
    y_pred = model.predict(c)
    map_characters = {0: 'IDC(-)', 1: 'IDC(+)'}
    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) 

runKerasCNNAugment(X_trainRosReshaped, Y_trainRosHot, X_testRosReshaped, Y_testRosHot,2,class_weight2)

Вот мой результат

И результат здесь:

Epoch 1/8
1299/1298 [==============================] - 27s 21ms/step - loss: 0.5580 - acc: 0.7216 - val_loss: 0.5227 - val_acc: 0.7386
Epoch 2/8
1299/1298 [==============================] - 27s 21ms/step - loss: 0.5260 - acc: 0.7466 - val_loss: 0.5321 - val_acc: 0.7298
Epoch 3/8
1299/1298 [==============================] - 27s 21ms/step - loss: 0.5175 - acc: 0.7512 - val_loss: 0.5170 - val_acc: 0.7412
Epoch 4/8
1299/1298 [==============================] - 27s 21ms/step - loss: 0.5166 - acc: 0.7556 - val_loss: 0.5086 - val_acc: 0.7528
Epoch 5/8
1299/1298 [==============================] - 27s 21ms/step - loss: 0.5141 - acc: 0.7562 - val_loss: 0.5017 - val_acc: 0.7572
Epoch 6/8
1299/1298 [==============================] - 27s 21ms/step - loss: 0.5119 - acc: 0.7602 - val_loss: 0.5061 - val_acc: 0.7515
Epoch 7/8
1299/1298 [==============================] - 27s 21ms/step - loss: 0.5090 - acc: 0.7591 - val_loss: 0.4999 - val_acc: 0.7611
Epoch 8/8
1299/1298 [==============================] - 27s 21ms/step - loss: 0.5100 - acc: 0.7624 - val_loss: 0.5043 - val_acc: 0.7539

Keras CNN #1C - accuracy: 0.7538994800234126

Спасибо!

1 Ответ

0 голосов
/ 30 апреля 2018

Что может случиться, так это то, что, хотя точность выглядит многообещающей, никакого реального прогноза не делается. Под этим я подразумеваю, что модель может очень быстро сходиться к простому решению, такому как маркировка всего как отрицательного. Это приводит к разумной точности, в зависимости от данных, которые вы используете, но ничего не говорит.
Я бы предложил тренировать модель и использовать ее для прогнозирования нескольких изображений. Затем верните выходные данные обратно в удобочитаемый для человека формат, скорее всего, в изображение, и посмотрите, предсказал ли он что-либо или все ли это отрицательные или положительные метки.

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