当前位置: 首页 > 知识库问答 >
问题:

Keras CNN相同输出

薛烈
2023-03-14

我用python用800个样本训练了一个CNN神经网络,并用60个样本进行了测试。输出精度是50,现在每次我使用模型。预测它会给我同样的结果。

#main file - run this to train the network

import numpy as np
from keras.datasets import cifar10
from datasetFetch import DataFetch
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.constraints import maxnorm
from keras.optimizers import SGD
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.utils import np_utils
from keras import backend as K
K.set_image_dim_ordering('th')
import simplejson
from matplotlib import pyplot
from scipy.misc import toimage
# load data
#(X_train, y_train), (X_test, y_test) = cifar10.load_data()
# create a grid of 3x3 images
#for i in range(0, 9):
#   pyplot.subplot(3,3,1 + i)
#   pyplot.imshow(toimage(X_train[i]))
# show the plot
#pyplot.show()

#init data
CONST_PHOTOS = 400 # number of photos of each type
y_train = []

#train data
data = DataFetch('orange',CONST_PHOTOS)
data1 = data.openPictures()
data = DataFetch('apple', CONST_PHOTOS)
data.removeErrorImages()
data2 = data.openPictures()

#test data
tdata = DataFetch('test-orange',30)
tdata1 = tdata.openPictures()
tdata = DataFetch('test-apple',30)
tdata2 = tdata.openPictures()

#add togheter data
X_train = data.connectData(data1,data2,'train')
y_train = data.getYtrain('train')
X_test = tdata.connectData(tdata1,tdata2,'test')
y_test = tdata.getYtrain('test')

# fix random seed for reproducibility
seed = 7
np.random.seed(seed)

# normalize inputs from 0-255 to 0.0-1.0
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train = X_train / 255.0
X_test = X_test / 255.0

#one hot encode outputs
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
num_classes = y_train.shape[1] #number of categories


# Create the model
model = Sequential()
model.add(Conv2D(224, (11, 11), input_shape=(224, 224, 3), activation='relu', padding='same'))
model.add(Dropout(0.2))
model.add(Conv2D(55, (5, 5), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2), data_format="channels_last"))
model.add(Conv2D(13, (3, 3), activation='relu', padding='same'))
model.add(Dropout(0.5))
model.add(Conv2D(13, (3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2), data_format="channels_last"))
model.add(Flatten())
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu', kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(Dense(num_classes, activation='softmax'))

# Compile model
epochs = 100
lrate = 0.01
decay = lrate/epochs
sgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)
model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
#print(model.summary())
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=epochs, batch_size=10)

# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Accuracy: %.2f%%" % (scores[1]*100))

#and then we save
# serialize model to JSON
model_json = model.to_json()
with open("Data/model.json", "w") as json_file:
    json_file.write(simplejson.dumps(simplejson.loads(model_json), indent=4))
# serialize weights to HDF5
model.save_weights("Data/model.h5")
print("Saved model to disk")

我用了keras和tensorflow。图像为224x224像素,每个像素分为两类。我对神经网络知之甚少,这是我第一次尝试把它做得这么大。我听说它可能太合适了,或者我需要一个更重要的图层,或者我的批量大小/年代/学习率是错误的。

编辑1:种子对网络培训有何影响?训练后,准确率为50%,并使用单独的。py文件,它只加载模型并对其使用predict函数,返回我使用的任何图像的确切输出百分比。我尝试了用于训练的图像和外部图像。我添加了dataFetch代码。

    #preparing the photos to be 224x224 and getting them from urls saved in txt files

from PIL import Image
import requests
from io import BytesIO
import numpy as np
import socket
import random
from scipy import misc
from PIL import ImageChops
import math, operator
from functools import reduce
import glob
import os
import signal

compare = Image.open('/home/mihai/PycharmProjects/neuralnet/compare.jpg')
compare1 = Image.open('/home/mihai/PycharmProjects/neuralnet/compare1.jpg')
compare2 = Image.open('/home/mihai/PycharmProjects/neuralnet/compare2.jpg')
compare3 = Image.open('/home/mihai/PycharmProjects/neuralnet/compare3.jpg')
compare4 = Image.open('/home/mihai/PycharmProjects/neuralnet/compare4.jpg')

def rmsdiff(im1, im2):
    "Calculate the root-mean-square difference between two images"

    h = ImageChops.difference(im1, im2).histogram()

    # calculate rms
    return math.sqrt(reduce(operator.add, map(lambda h, i: h*(i**2), h, range(256))) / (float(im1.size[0]) * im1.size[1]))

class DataFetch:

    chosenFile = ''
    maxNumber = 0
    y_train = []
    y_test = []

    def __init__(self, choice, number):
        print('Images with '+choice+'s are being prepared')
        self.chosenFile = choice
        self.maxNumber = number

    def getPictures(self):
        imgArr = np.zeros((self.maxNumber, 224, 224, 3), dtype='uint8')
        count = 0
        class timeoutError(Exception):
            signal.alarm(0)
        def handler(signum, frame):
            raise timeoutError
        with open(self.chosenFile, "r") as ins:
            for line in ins:
                if count < self.maxNumber:
                    signal.signal(signal.SIGALRM, handler)
                    signal.alarm(3)
                    try:
                        try:
                            r = requests.get(line)
                            try:
                                img = Image.open(BytesIO(r.content))
                                ok = 0
                                try:
                                    if rmsdiff(compare, img) > 1.3 and rmsdiff(compare1, img) > 1.3 and rmsdiff(compare2, img) > 1.3 and rmsdiff(compare3, img) > 1.3 and rmsdiff(compare4, img) > 1.3:
                                        ok = 1
                                    else:
                                        print('Image removed from website')
                                except ValueError:
                                    ok = 1
                                if ok == 1:
                                    img = img.resize((224, 224))
                                    img = img.convert('RGB')
                                    img.save('/home/mihai/PycharmProjects/neuralnet/images/'+self.chosenFile+'/'+str(count)+".jpg", 'JPEG')
                                    imgArr[count, :, :, :] = img
                                    count = count + 1
                                    print(count)
                            except OSError:
                                print('Image not Available')
                        except socket.error:
                            print('URL not available')
                    except timeoutError:
                        print("URL not available")
        return imgArr

    def openPictures(self):
        cdir = os.getcwd()
        imgArr = np.zeros((self.maxNumber, 224, 224, 3), dtype='uint8')
        count = 0
        for filename in glob.glob(cdir+'/images/'+self.chosenFile+'/*.jpg'):
            if count < self.maxNumber:
                img = Image.open(filename)
                imgArr[count, :, :, :] = img
                count = count + 1
        return imgArr

    def removeErrorImages(self):
        cdir = os.getcwd()
        for filename in glob.glob(cdir+'/images/'+self.chosenFile+'/*.jpg'):
            img = Image.open(filename)
            try:
                if rmsdiff(compare, img) < 1.3 or rmsdiff(compare1, img) < 1.3 or rmsdiff(compare2, img) < 1.3 or rmsdiff(compare3, img) < 1.3 or rmsdiff(compare4, img) < 1.3:
                    os.remove(cdir+'/images/'+self.chosenFile+'/'+filename+'.jpg')
            except ValueError:
                pass

    def getYtrain(self,outParam):
        if outParam == 'train':
            self.y_train = np.reshape(self.y_train, (len(self.y_train), 1))
            return self.y_train
        else:
            self.y_test = np.reshape(self.y_test, (len(self.y_test), 1))
            return self.y_test

    def connectData(self, data1, data2, outParam):
        d1c = 0
        d2c = 0
        outList = []
        X_train = np.zeros((2 * self.maxNumber, 224, 224, 3), dtype='uint8')
        for i in range(2 * self.maxNumber):
            if d1c < self.maxNumber and d2c <self.maxNumber:
                if random.random() <= 0.5:
                    X_train[d1c + d2c, :, :, :] = data1[d1c, :, :, :]
                    d1c = d1c + 1
                    outList.append(0)
                else:
                    X_train[d1c + d2c, :, :, :] = data2[d2c, :, :, :]
                    d2c = d2c + 1
                    outList.append(1)
            else:
                if d1c < self.maxNumber:
                    X_train[d1c + d2c, :, :, :] = data1[d1c, :, :, :]
                    d1c = d1c + 1
                    outList.append(0)
                else:
                    if d2c < self.maxNumber:
                        X_train[d1c + d2c, :, :, :] = data2[d2c, :, :, :]
                        d2c = d2c + 1
                        outList.append(1)
        if outParam == 'train':
            self.y_train = outList
        else:
            if outParam == 'test':
                self.y_test = outList
        return X_train

预测代码:

#run this to test a sample

from keras.utils import np_utils
from keras.models import model_from_json
from keras.optimizers import SGD
from datasetFetch import DataFetch

# load json and create model
json_file = open('Data/model2.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)

# load weights into new model
loaded_model.load_weights("Data/model2.h5")
print("Loaded model from disk")

epochs = 100
lrate = 0.01
decay = lrate/epochs
sgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)
loaded_model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])

#prepare X_test
tdata = DataFetch('test-orange',int(3))
tdata1 = tdata.openPictures()
tdata = DataFetch('test-apple',int(3))
tdata2 = tdata.openPictures()
X_test = tdata.connectData(tdata1,tdata2,'test')
y_test = tdata.getYtrain('test')
X_test = X_test.astype('float32')
X_test = X_test / 255.0
y_test = np_utils.to_categorical(y_test)
print('Number of samples to be tested: '+str(X_test.shape[0]))

scores = loaded_model.evaluate(X_test, y_test, verbose=0)
print(scores[1]*100)

score = loaded_model.predict(X_test,batch_size=6, verbose=1)
print(score) #prints percentages

共有1个答案

宿衡虑
2023-03-14

图像准备是正确的。问题在于神经网络的结构和使用的优化方法。

由于仅用于分类2类的神经元数量巨大,结构过于拟合,导致准确率保持在50%。

第二个问题是sgd优化器。我改为:

opt=keras.optimizers.rmsprop(lr=0.0001, decay=1e-6)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy']

希望这对其他人也有帮助!

 类似资料:
  • 我有一个棘手的问题要解决。我使用系统。方法调用之前和之后的currentTimeMillis(),因为我必须测量这两条语句之间经过的时间。 我担心的是每次运行程序都会得到不同的结果。 我明白了(这很完美): 几秒钟后,我再次运行程序,我得到(这是错误的): 我说这个输出是错误的,因为每辆车的等待时间不应该少于100毫秒。 什么实际影响基于currentTimeMillis函数的时间计算? 为什么我

  • 我需要从30fps的视频中提取帧两次:(I)720p png帧,(ii)270p tiff帧。 我分别使用以下命令来实现这一点: 然而,这导致第一命令输出35,776帧,第二命令输出35,812帧,尽管视频是相同的,并且所请求的framerate是30fps。 这是什么原因造成的?如何确保ffmpeg输出相同数量的(同步)帧?

  • 问题内容: 我有非常简单的案例,可以将要完成的工作分解并分配给工人。我从这里尝试了一个非常简单的多处理示例: 上面的程序产生以下输出: 为什么要打印相同的随机数?(我的机器上有4个CPU)。这是最好/最简单的方法吗? 问题答案: 我认为您需要在函数中使用numpy.random.seed重新设置随机数生成器。 我的猜测是,当您导入模块时,随机数生成器(RNG)会被植入种子。然后,当您使用多处理时,

  • 问题内容: 我正在使用具有Spring安全性的BCryptPasswordEncoder。我的期望是,对于相同的输入,我将始终获得相同的输出。但是对于相同的输入,我得到不同的输出。您可以使用以下代码段对其进行测试: 输出:$ 2a $ 10 $ cYLM.qoXpeAzcZhJ3oXRLu9Slkb61LHyWW5qJ4QKvHEMhaxZ5qCPi 输出2:$ 2a $ 10 $ KEvYX9y

  • 我需要我的logstash conf文件向一个kafka主题发送一条消息,以指示已处理的文档已发送到ElasticSearch。我已经准备好了logstash文件来构造发送到ElasticSearch的数据,但是我需要通过同一个logstash文件向kafka主题发布“是”或“否”消息。

  • 我正在使用带有Spring Security的BCryptPasswordEncoder。我的期望是,对于相同的输入,我总是得到相同的输出。但是对于相同的输入,我得到不同的输出。您可以使用下面的代码片段对其进行测试: 输出:$2A$10$CYLM.QOXPEAZCZHJ3OXRLU9SLKB61LHYWW5QJ4QKVHEMHAXZ5QCPI 输出2:$2A$10$kevyx9yjj0f1x3wl