了解CNN超参数

时间:2019-11-25 11:42:49

标签: python tensorflow machine-learning neural-network conv-neural-network

关于卷积神经网络,我有一些问题。我的代码绝不是干净的,因此我正手道歉。

首先,我有一个包含10.000张尺寸为(28,28,1)的图像的数据集。我的愿望是建立一个卷积神经网络,将这些图像分类为5个不同的类(这是著名的Zalando数据集的一半)。

这是我的代码

class layers(ABC): 
    def __init__(self, filter_size, number_of_neurons, fully_conn_neurons):
        self.filter_size = filter_size #placeholder for filter 
        self.number_of_neurons = number_of_neurons #The number of neurons
        self.fully_conn_neurons = fully_conn_neurons #Amount of neurons in the last layer

        return

class new_conv_layer(ABC):
    def __init__(self, filters, number_of_filters, initial_input, namew, nameb, defrel):
        self.filters = filters
        self.number_of_filters = number_of_filters #16 is amount of filters
        self.color_chan = 1
        self.shape = [filters, filters, self.color_chan, number_of_filters]
        self.defrel = False

        self.weight = tf.get_variable(name=namew, shape =self.shape, initializer = tf.initializers.glorot_normal)
        self.bias = tf.Variable(tf.constant(0.05, shape = [number_of_filters], name=nameb))

        self.layer = tf.nn.conv2d(input = initial_input, filter = self.weight, strides=[1,2,2,1], padding="SAME")
        self.layer += self.bias 

        self.layer = tf.nn.max_pool(value=self.layer, ksize = [1,2,2,1], strides = [1,2,2,1], padding="SAME")

        if defrel == True:
            self.layer = tf.nn.relu(self.layer)


    def flatten(self):
        flat_shape = self.layer.shape
        self.features = flat_shape[1:].num_elements()
        self.layer = tf.reshape(self.layer, [-1, self.features])

        return self.layer, self.features

x = tf.placeholder(tf.float32, shape=[None, 784], name='x')
x_image = tf.reshape(x, [-1, 28, 28, 1])
y = tf.placeholder(tf.float32, [None, 5])



layer1 = new_conv_layer(filters=4,number_of_filters=16, initial_input= x_image, namew ="w", nameb="b", defrel=True)
layer2 = new_conv_layer(filters=4,number_of_filters=32, initial_input=layer1.layer, namew="fuckoff", nameb="fuck", defrel=False)


layer_flat, num_features = layer2.flatten()


class fully_connected(ABC):
    def __init__(self, previous_layer, inp, outp, namea, nameb):

        self.previous_layer = previous_layer
        self.weights = tf.get_variable(shape =[inp, outp], initializer = tf.initializers.glorot_normal, name=namea)
        self.biases = tf.Variable(tf.constant(0.05, shape = [outp], name = nameb))
        self.temp_layer = tf.matmul(self.previous_layer, self.weights) + self.biases
        self.new_layer = tf.nn.relu(self.temp_layer)






layer_fc1 = fully_connected(layer_flat, inp=num_features, outp=128, namea = "t", nameb= "u")
layer_fc2 = fully_connected(layer_fc1.new_layer, inp=128, outp=5, nameb="h", namea="z")



epochs = 300
learning_rate = 0.05
batch_size = 128


pred = tf.nn.softmax(layer_fc2.new_layer)
print(pred.shape)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = pred, labels = y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))


# drop out, regularization 
# call back 

init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init) 
    train_loss = []
    test_loss = []
    train_accuracy = []
    test_accuracy = []
    summary_writer = tf.summary.FileWriter('./Output', sess.graph)
    for i in range(epochs):
        for batch in range(len(train_X)//batch_size):
            batch_x = train_X[batch*batch_size:min((batch+1)*batch_size,len(train_X))]
            batch_y = train_y[batch*batch_size:min((batch+1)*batch_size,len(train_y))]    
            opt = sess.run(optimizer, feed_dict={x: batch_x,
                                                              y: batch_y})
            loss, acc = sess.run([cost, accuracy], feed_dict={x: batch_x,
                                                              y: batch_y})
        print("Iter " + str(i) + ", Loss= " + \
                      "{:.6f}".format(loss) + ", Training Accuracy= " + \
                      "{:.5f}".format(acc))
        print("Optimization Finished!")


        test_acc,valid_loss = sess.run([accuracy,cost], feed_dict={x: test_X,y : test_y})
        train_loss.append(loss)
        test_loss.append(valid_loss)
        train_accuracy.append(acc)
        test_accuracy.append(test_acc)
        print("Testing Accuracy:","{:.5f}".format(test_acc))
    summary_writer.close()

我遇到两个不同的问题:我无法更改过滤器,因为它会给我错误:InvalidArgumentError:输入和过滤器必须具有相同的深度:16与1。其次,我的测试精度仅为50 %绝对不好。.

我知道这是非常广泛的,但是我严重缺少什么吗?

1 个答案:

答案 0 :(得分:1)

self.color_chan = 1是错误的。对于初始输入,图像确实具有单个通道,但是在第一层之后,它具有16个通道(因为第一层具有16个滤镜)。更改为self.color_chan = int(initial_input.shape[3])之类的内容。

关于精度,我不确定如果您也遇到此错误,您将如何获得结果,但是无论如何,请注意,尽管50%的精度不好,但它比随机精度要好(五堂课大约是20%)。您可能需要对滤镜大小等进行进一步的试验以进行改进(由于它是众所周知的数据集,因此您可以尝试重现几个示例)。该数据集专门设计为与MNIST“兼容”,但无论如何都要困难得多。