首页 > 解决方案 > 为什么在应用 vggnet 时这不太准确?

问题描述

我对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

谢谢你!

标签: tensorflowmachine-learningneural-networkdeep-learningkeras

解决方案


可能发生的情况是,虽然准确性看起来很有希望,但并没有做出实际的预测。我的意思是,模型可能会很快收敛到一个简单的解决方案上,例如将所有内容标记为负数。然后,这会导致合理的准确性,具体取决于您使用的数据,但什么也没说。
我建议训练模型并使用它来预测一些图像。然后将输出转换回人类可读的格式,很可能是一张图片,并查看它是否预测了某些东西,或者它是否都是负面或正面标签。


推荐阅读