2017-06-02 31 views
0

私はCNNニューラルネットワークのpythonで800サンプルをテストし、それを60でテストしました。 を予測します。同じ結果です。ケラスCNN同じ出力

#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") 

私は tensorflow kerasを使用。画像は224x224ピクセルで、それぞれ2つのカテゴリに分かれています。私はニューラルネットワークについてはあまりよく分かりませんが、これは私の最初の試みです。私はそれ以上のフィットかもしれない、または多分私は1つのより重要な層、または多分私のバッチサイズ/エポック/レートを学ぶ間違っている必要があります聞いた。

助けてください!

Edit1:シードはどのようにネットワークのトレーニングに影響しますか? トレーニング後、精度は正確に50%で、モデルをロードして予測機能を使用する別の.pyファイルを使用することにより、使用する画像の正確な出力割合が返されます。私は訓練用と外部用の両方の画像を試しました。 私は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 
+0

固定ランダムシードを設定しているため正確さは同じです –

+0

「同じ結果をもたらす」とはどういう意味ですか?それは、あなたがそれに渡す入力と同じ予測をするか、同じ入力を渡すと常に50%の精度を得ますか? – gionni

+0

ああ、申し訳ありませんが、同じスクリプトでmodel.predictを使用したと思います。トレーニングフェーズでモデルの精度/損失はどのくらいですか?モデル予測を使用する前にデータとモデルを再ロードする方法は? –

答えて

0

は、画像準備は正しかったです。問題はニューラルネットの構造と使用された最適化方法にありました。

わずか2つのクラスを分類するために使用される膨大な数のニューロンがあるため、構造がオーバーフィッティングであり、精度が50%に留まります。

2番目の問題は、sgdオプティマイザの問題です。私が代わりに使用:これは、同様に他の人を助け

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

願っています!

関連する問題