我有一个这样的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)