为什么在应用vggnet时这不太准确?

时间:2018-04-30 01:03:03

标签: tensorflow machine-learning neural-network deep-learning keras

我对CNN感兴趣。所以,我想在我的代码中使用VGGnet。训练时,准确度仅略有提高。当我在不使用vggnet的情况下应用简单的CNN时,准确率为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 :(得分:0)

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