Простая сверточная нейронная сеть не может снизить ее стоимость - PullRequest
0 голосов
/ 31 декабря 2018

Я сделал свой первый CNN, используя тензорный поток.Цель состоит в том, чтобы определить, есть ли собака или кошка на черно-белой фотографии размером 100x100 пикселей.Проблема в странном поведении / выходе из нейронной сети.Первый вывод в порядке, но другие слишком экстремальные.Я думаю, что Raw Output (последние значения перед softmax), возможно, слишком высок.Но я не могу найти способ уменьшить его.То, что я уже безуспешно пытался:

  • Изменение веса и смещения от random_normal к единицам и нулям
  • Снижение скорости обучения
  • Использование tf.image.per_image_standardization()

Мой код:

from PIL import Image
import tensorflow as tf
import numpy as np
import os, random

nClasses = 2
iHeight = 100
iWidth = 100

ds=[]


w = {
    "w1": tf.Variable(tf.ones([5,5,1,32],dtype=float)),
    "w2": tf.Variable(tf.ones([5,5,32,64],dtype=float)),
    "w3": tf.Variable(tf.ones([90*90*64,50],dtype=float)),
    "w4": tf.Variable(tf.ones([50,2],dtype=float)),


}

b = {
        "b1": tf.Variable(tf.zeros([32], dtype=float)),
        "b2": tf.Variable(tf.zeros([64], dtype=float)),
        "b3": tf.Variable(tf.zeros([50], dtype=float)),
        "b4": tf.Variable(tf.zeros([2], dtype=float)),

}


def loadImage(path):
    img = Image.open(path)
    data = np.asarray(img,dtype=float)
    return data



for file in os.listdir("dataset/cat/"):
    ds.append({"input":loadImage("dataset/cat/"+file), "output":np.array([[1,0]],dtype=float)})

for file in os.listdir("dataset/dog/"):
    ds.append({"input":loadImage("dataset/dog/"+file), "output":np.array([[0,1]],dtype=float)})

rawInput = tf.placeholder(tf.float32, [iWidth, iHeight], name="input")
output = tf.placeholder(tf.float32, [None, nClasses], name="iClass")

input = tf.reshape(rawInput, [-1,100,100,1])

#First convolution and pooling
conv1 = tf.nn.conv2d(input, w["w1"], strides=[1,1,1,1], padding="VALID")
conv1_b = tf.nn.bias_add(conv1, b["b1"])
conv1_a = tf.nn.relu(conv1_b)

pool1 = tf.nn.max_pool(conv1_a,[1,2,2,1],strides=[1,1,1,1], padding = "VALID")

#Second convolution and pooling
conv2 = tf.nn.conv2d(pool1, w["w2"], strides=[1,1,1,1], padding="VALID")
conv2_b = tf.nn.bias_add(conv2, b["b2"])
conv2_a = tf.nn.relu(conv2_b)

pool2 = tf.nn.max_pool(conv2_a,[1,2,2,1],strides=[1,1,1,1], padding = "VALID")

#Transforming to the first fully connected layer
pool2_fcl = tf.reshape(pool2,[1, 90*90*64])
fcl1=tf.matmul(pool2_fcl,w["w3"])
fcl1_b=tf.nn.bias_add(fcl1,b["b3"])
fcl1_a=tf.nn.relu(fcl1_b)


#Second fully connected layer
fcl2=tf.matmul(fcl1,w["w4"])
fcl2_b =tf.nn.bias_add(fcl2,b["b4"])
pred= tf.nn.softmax(fcl2_b)

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=fcl2_b,labels=output))
optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(cost)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    for x in range (100):
        y = random.randint(0,len(ds)-1)
        optimizerVal,rawOutput, predVal,labelVal,costVal = sess.run([optimizer,fcl2_b,pred,output,cost],feed_dict={rawInput:ds[y]["input"], output:ds[y]["output"]})
        print("Raw Output (fcl2_b): %s\nPred: %s\nLabel: %s\nCost:%s\n\n"%(rawOutput, predVal,labelVal,costVal))
    print(b["b1"].eval())

Вывод:

Необработанный вывод (fcl2_b): [[1.0071293e + 14 1.0071293e + 14]] Пред: [[0.5 0.5]] Метка: [[1.0.]] Стоимость: 0,6931472

Необработанный выход (fcl2_b): [[1.0680586e + 14 1.0680579e + 14]] Pred: [[1.0.]] Метка: [[1.0.]] Стоимость: 0,0

Необработанный выход (fcl2_b): [[6,8944283e + 13 6,8944161e + 13]] Pred: [[1.0.]] Метка: [[0.1.]] Стоимость: 121634820,0

Необработанный выход (fcl2_b): [[5.6959584e + 13 5.6959487e + 13]] Пред: [[1.0.]] Метка: [[1.0.]] Стоимость: 0,0

Необработанный выход (fcl2_b): [[8,481456e + 13 8,481446e + 13]] Pred: [[1.0.]] Метка: [[0.1.]] Стоимость: 92274690.0

Спасибо за помощь!

1 Ответ

0 голосов
/ 31 декабря 2018

Попробуйте изменить инициализацию веса:

tf.Variable(tf.random_normal([5,5,1,32]), dtype=tf.float32)

Смещения в порядке, но вы должны «нарушить симметрию» весов.См. Например здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...