神经网络做出的预测不正确

时间:2019-07-25 21:20:10

标签: python machine-learning neural-network

我正在尝试从头开始构建神经网络,以在最小的数据库上进行图像识别,但是代码不仅产生了错误的答案,而且似乎还遥不可及。

我试图在中间步骤中查看权重和偏差,但是由于无法知道应该是什么权重和偏差,所以我不知道如何解决。

import tensorflow as tf
import matplotlib.pyplot as plt
(xtrain,ytrain),(xtest,ytest)=tf.keras.datasets.mnist.load_data()
import numpy as np
import random
flatlist1=[x.flatten() for x in xtrain]
flatlist2=[x.flatten() for x in xtest]
traininp=[]
testinp=[]
for i in range(len(ytrain)):
    traininp.append([flatlist1[i],ytrain[i]])
for i in range(len(ytest)):
    testinp.append([flatlist1[i],ytest[i]])
def sigmoid(x):
        return 1.0/(1.0+np.exp(-x))
def sigmoid_der(x):
        return sigmoid(x)*(1-sigmoid(x))

def relu(x):
        return max(0,x)
def relu_der(x):
        if x>0:
                return 1
        else:
                return 0

class NeuralNetwork(object):

    def __init__(self,traininp,layers):
        #Add a list layer provideing no of nodes in each layer
        #add training input as array of pixel grayscale values and output in a list
        self.num_layers = len(layers)
        self.layers = layers.insert(0,len(traininp[0][0]))
        self.weights=[]
        self.biases = [((np.random.randn(y, 1)).flatten()).tolist() for y in layers[1:]]
        for y in range(1,len(layers[1:])+1):
            weight=[]
            for x in range(layers[y]):
                weight.append(((np.random.randn(layers[y-1],1)).flatten()).tolist() )
            self.weights.append(weight)

        self.nweights=[]
        self.nbiases=[]
        for i in range(len(self.weights)):
            w=[]
            for j in self.weights[i]:
                w.append([0]*len(j))
            self.nweights.append(w)
        for i in self.biases:
            self.nbiases.append([0]*len(i))
            x=0
        for i in range(10):
            for k in range(20):
                predictions=self.feedforward(traininp[x][0],layers)
                dbiases,dweights=self.Backprop(traininp[x][1],predictions)
                self.nbiases=self.addbiases(self.nbiases,dbiases)
                self.nweights=self.addweights(self.nweights,dweights)
                x+=1
            self.updateb(self.biases,self.nbiases,0.1,20)
            self.updatew(self.weights,self.nweights,0.1,20)
        for i in range(190,210):
            predictions=self.feedforward(traininp[i][0],layers)
            print(predictions[-1],predictions[-1].index(max(predictions[-1])),traininp[i][1])

    def calculate(self,inp,weights,bias):
        wsum=0.0
        for x,y in zip(weights,inp):
            wsum+=x*y
        return (wsum+bias)

    def feedforward(self,traininp,layers):
        firstz=[self.calculate(traininp,self.weights[0][i],self.biases[0][i]) for i in range(layers[1])]
        firstlayer=[sigmoid(i) for i in firstz]
        outputlayers=[]
        outputlayers.append((traininp).tolist())
        self.zs=[]
        self.zs.append(firstz)
        outputlayers.append(firstlayer)
        for x in range(1,len(layers[1:])):
            z=[]
            k=[]
            for i in range(layers[x+1]):
                z.append(self.calculate(outputlayers[x-1],self.weights[x][i],self.biases[x][i]))
                k.append(sigmoid(z[i]))
            self.zs.append(z)
            outputlayers.append(k)
        return(outputlayers)

    def Backprop(self,traininp,predictions):
        dweights=[]
        dbiases=[]
        dnodes=[]
        dweights=self.nweights.copy()
        dbiases=self.nbiases.copy()
        y=[0]*len(predictions[-1])
        y[traininp]=1
        for i in predictions:
            dnodes.append([0]*len(i))
        for i in range(len(y)):
            dbiases[-1][i]=sigmoid_der(self.zs[-1][i])*self.cost(predictions[-1][i],y[i])
            for j in range(len(predictions[-2])):
                dweights[-1][i][j]=predictions[-2][j]*sigmoid_der(self.zs[-1][i])*self.cost(predictions[-1][i],y[i])
            dweights[-1][i][j]/=j
            for j in range(len(self.weights[-1])):
                for k in range(len(self.weights[-1][j])):
                    dnodes[-1][i]=self.weights[-1][j][k]*sigmoid_der(self.zs[-1][i])*self.cost(predictions[-1][i],y[i])
                dnodes[-1][i]/=k
        for k in range(2,self.num_layers+1):
            for i in range(len(predictions[-k])):
                dbiases[-k][i]=sigmoid_der(self.zs[-k][i])*self.cost(predictions[-k][i],dnodes[-k][i])
                for j in range(len(self.weights[-k])):
                    for l in range(len(self.weights[-k][j])):
                        dnodes[-k][i]=self.weights[-k][j][l]*sigmoid_der(self.zs[-k][i])*self.cost(predictions[-k][i],dnodes[-k][i])
                    dnodes[-k][i]/=l
                for j in range(len(predictions[-k-1])):
                    dweights[-k][i][j]=predictions[-k-1][j]*sigmoid_der(self.zs[-k][i])*self.cost(predictions[-k][i],dnodes[-k][i])
                dweights[-k][i][j]/=j
        return (dbiases,dweights)        

    def cost(self,output,y):
        return (2*(output-y))

    def addbiases(self,list1,list2):
        listo=[]
        for i,j in zip(list1,list2):
            listt=[]
            for k,l in zip(i,j):
                listt.append(k+l)
            listo.append(listt)
        return listo

    def addweights(self,list1,list2):
        listo=[]
        for i,j in zip(list1,list2):
            lists=[]
            for k,l in zip(i,j):
                listt=[]
                for p,q in zip(k,l):
                    listt.append(p+q)
                lists.append(listt)
            listo.append(lists)
        return listo

    def updatew(self,list1,list2,eta,bsize):
        listo=[]
        for i,j in zip(list1,list2):
            lists=[]
            for k,l in zip(i,j):
                listt=[]
                for p,q in zip(k,l):
                    listt.append(p-(eta/bsize)*q)
                lists.append(listt)
            listo.append(lists)
        return listo

    def updateb(self,list1,list2,eta,bsize):
        listo=[]
        for i,j in zip(list1,list2):
            listt=[]
            for k,l in zip(i,j):
                listt.append(k-(eta/bsize)*l)
            listo.append(listt)
        return listo


n1=NeuralNetwork(traininp[0:210],[5,5,10])

我至少希望它像神经网络一样工作,即使它的准确性不高或工作速度很慢。

0 个答案:

没有答案