CNN准确率不准确

我有一个这样的CNN模型

import pandas as pdimport numpy as npimport cv2import matplotlib.pyplot as pltfrom tensorflow.keras.layers import *from tensorflow.keras.models import *import randomimport pickledf = pd.read_csv('minor/age_gender.csv')image_list = []labels = []image_labels = []print(df.shape[0])for x in range(df.shape[0]):    png = np.fromstring(df.iloc[x]['pixels'], dtype=int, sep=' ').reshape((48,48,1))    png = png/250.0    age = df.iloc[x]['age']        minor=None    if int(age)<18:        #print(2)        minor =1    else:        minor = 0    image_labels.append((png,minor))young = []old = []for png,minor in image_labels:    if minor==1:        young.append((png,minor))    else:        old.append((png,minor))pickle.dump(young,open('minor/young.pickle','wb'))print('saved')input()young = young[:min(len(young),len(old))]old = old[:min(len(young),len(old))]print(len(young))input()image_labels = old+youngprint(image_labels)input()random.shuffle(image_labels)for png,minor in image_labels:    image_list.append(png)    print(minor)    labels.append(minor)    image_list=np.array(image_list)labels = np.array(labels)print(image_list.shape)#imag_list = image_list.reshape(-1,48,48,1)print(image_list.shape)def model2():    inputs = Input((None,None,1))    x = Conv2D(128,(5,5),input_shape = (48,48,1),padding='same')(inputs)     x= BatchNormalization()(x)    x = Activation('relu')(x)    x = Conv2D(64,(5,5),padding='same')(x)        x= BatchNormalization()(x)    x = Activation('relu')(x)    x= BatchNormalization()(x)    x = Activation('relu')(x)    x = Conv2D(1,(5,5),padding='same')(x)    x=GlobalMaxPooling2D()(x)    outputs = Activation('sigmoid')(x)    model = Model(inputs=inputs,outputs=outputs)    model.compile('adam','binary_crossentropy',metrics=['accuracy'])    return modelinput()model = model2()print(model.summary())model.fit(image_list,labels,epochs=10,batch_size=32)model.save('minor/age_detection6')

当我运行它时,我得到的训练日志看起来像这样

Epoch 1/10265/265 [==============================] - 40s 148ms/step - loss: 0.6445 - accuracy: 0.6447Epoch 2/10265/265 [==============================] - 37s 139ms/step - loss: 0.4422 - accuracy: 0.7994Epoch 3/10265/265 [==============================] - 37s 138ms/step - loss: 0.4186 - accuracy: 0.8168Epoch 4/10265/265 [==============================] - 37s 138ms/step - loss: 0.3720 - accuracy: 0.8381Epoch 5/10265/265 [==============================] - 37s 138ms/step - loss: 0.3559 - accuracy: 0.8517Epoch 6/10265/265 [==============================] - 39s 149ms/step - loss: 0.3487 - accuracy: 0.8564Epoch 7/10265/265 [==============================] - 40s 151ms/step - loss: 0.3341 - accuracy: 0.8597Epoch 8/10265/265 [==============================] - 37s 139ms/step - loss: 0.3252 - accuracy: 0.8699Epoch 9/10265/265 [==============================] - 37s 139ms/step - loss: 0.3084 - accuracy: 0.8765Epoch 10/10265/265 [==============================] - 37s 138ms/step - loss: 0.3074 - accuracy: 0.8746

到目前为止一切正常。准确率相当高。这里开始变得奇怪了。在下面的代码中

import cv2import numpy as npfrom tensorflow.keras.models import load_modelimport pandas as pdimport picklefrom tqdm import tqdmmodel = load_model('minor/age_detection6')df = pd.read_csv('minor/age_gender.csv')image_list = []labels = []print(df.shape[0])for x in range(df.shape[0]):    png = np.fromstring(df.iloc[x]['pixels'], dtype=int, sep=' ').reshape((48,48,1))    png = png/250.0    age = df.iloc[x]['age']        minor=None    if int(age)<18:        minor =1    else:        minor = 0    image_list.append(png)    labels.append(minor)print(labels.index(1))input()image2 = cv2.imread('minor/kid.png')print(image2.shape)image2 = cv2.cvtColor(image2,cv2.COLOR_BGR2GRAY)print(image2.shape)image = image_list[0]print(labels[0])image = image/255.0image = np.reshape(image,(1,image.shape[0],image.shape[1],1))image2 = image2/255.0image2 = np.reshape(image2,(1,image2.shape[0],image2.shape[1],1))print(image2.shape)input()valu = 0predictions=model.predict(image)print(predictions)for items in predictions:    for item in items:        valu+=itemvalu = int(valu/predictions.shape[0])print(valu)print(labels[0])young = pickle.load(open('minor/young.pickle','rb'))print('no')score = 0for png,minor in tqdm(young):    score += int(model.predict(png)[0][0])print(score/len(young))

我拍摄了一组未成年人的照片(其中一些模型已经训练过),但在预测所有这些照片时,成功率为0%。然而,对于非未成年人,成功率为100%。我的数据已经打乱并平衡,所以我对这种情况感到困惑。任何帮助将不胜感激。


回答:

通常在二元预测中,你需要设置一个阈值来将输出分为两个类别。你只是试图将输出(一个介于0和1之间的数字)直接放入你的类别中,而没有使用阈值。你的比较应该看起来像这样:

class_1_correct += np.sum(outputs>=0.5 * class_labels)class_0_correct += np.sum(np.abs(1 - outputs<0.5 * class_labels))

这只是一个例子,需要根据你的代码进行调整。

此外,这部分是错误的:

for png,minor in tqdm(young):    score += int(model.predict(png)[0][0])

你将sigmoid输出转换成了整数,这几乎总是等于零。

同样的问题也适用于这段代码:

valu = int(valu/predictions.shape[0])

我认为你应该这样做:

valu = int(valu/predictions.shape[0]*100)

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注