Я сделал свой первый 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
Спасибо за помощь!