更新:使用 0.075 的学习率,随机权重和随机偏差,误差总是达到 0.17277051191827117,然后不动。在 0.01 的学习率下,同样的情况也会发生,我得到的只是黑色图像。似乎错误要高得多,这应该很难弄清楚
...无论我将学习率设置为多少,它总是落在同一件事上
我一直在尝试建立网络,工作。它应该拍摄一张图像,将其分解为 rgb 输入,然后将它们传递并重新创建该图像。我想我终于明白了必须设置阵列的方式,但现在数学不起作用。它总是在某一点停止训练或来回走动。我使用了几种学习率。我尝试过使用更多隐藏层,但我没有内存。我确信有更好的方法。我想转移到像 Keras 这样的东西上,但我想通过动画层更好地理解事物是如何工作的,但事物只是没有训练。
我用这个例子来构建我的 https://gist.github.com/jamesloyys/ff7a7bb1540384f709856f9cdcdee70d#file-neural_network_backprop-py
该示例有效,我能够为图层设置动画。但该示例是关于根据输入猜测 1 或 0。
这是我正在使用的代码。它生成的图像总是黑色、白色或灰色。我正在使用 128x128 的小图像或类似大小的图像。任何更大的都会给我带来记忆错误。我已经对这段代码进行了一些改进,运行了几次,然后它会出错,因为形状没有对齐。我遇到了很多转置问题 (.T) 我也经常遇到 .exp 问题,因为小数会突然失控,而且无论我运行多久,这个例子都没有。我有一个 16 核处理器,可以相当快地处理大小合适的图像,并且可以使用 numba 来加快速度,尽管我遇到了大量错误。
请在数学和算法方面提供任何帮助,绝对有帮助,我会很感激
import os
from time import sleep, strftime
import cv2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import matplotlib.animation as animation
from numpy.linalg import multi_dot
from numba import njit, jit, prange
from inspect import getframeinfo, stack
DEB_TEXT = 1
MODE_TRAINING = 0
MODE_GENERATING = 0
RES_MOD = 1
VALUE = 0
WEIGHT = 1
BIAS = 2
ACTIVATION = 3
# Activation function
def sigmoid(t):
return 1.0 / (1.0 + np.exp(-t))
# Derivative of sigmoid
def sigmoid_derivative(p):
return p * (1 - p)
def debuginfo(d):
caller = getframeinfo(stack()[1][0])
print("%s:%d - %s" % (caller.filename, caller.lineno, d[1])) # python3 syntax print
sleep(d[0])
class mAiV2:
def __init__(self, mode):
self.run_mode = MODE_TRAINING
self.training_image = None
self.training_image_name = None
self.input_shape = None
self.output_target = None
self.learning_rate = .09
self.init_output_layers_res = None
self.init_hidden_color_layers_res = None
self.init_layer_four_res = None
self.init_output_layers_res = None
self.input_layer = None
self.w_input_layer_to_layer_one = None
self.layer_one_bias = None
self.layer_one = None
self.w_layer_one_to_layer_two = None
self.layer_two_bias = None
self.layer_two = None
self.w_layer_two_to_output_layer = None
self.output_layer = None
def train(self):
self.output_layer = self.process_forward()
self.process_backward()
#@jit
def process_forward(self):
self.layer_one = sigmoid(np.dot(self.input_layer, self.w_input_layer_to_layer_one)) + self.layer_one_bias
self.layer_two = sigmoid(np.dot(self.layer_one, self.w_layer_one_to_layer_two)) + self.layer_two_bias
self.output_layer = sigmoid(np.dot(self.layer_two, self.w_layer_two_to_output_layer))
return self.output_layer
#@jit
def process_backward(self):
#print("Weights 2 0")
self.Dw_layer_two_to_output_layer = np.dot(self.layer_two.T, 2 * (self.output_target - self.output_layer) * sigmoid_derivative(self.output_layer))
#print("Weights 1 2")
self.Dw_layer_one_to_layer_two = np.dot(self.layer_one.T, np.dot(
2 * (self.output_target - self.output_layer) * sigmoid_derivative(self.output_layer),
self.w_layer_two_to_output_layer.T) * sigmoid_derivative(self.layer_two))
#print("Weights i 1")
self.Dw_input_layer_to_layer_one = np.dot(self.input_layer.T, np.dot(
2 * (self.output_target - self.output_layer) * sigmoid_derivative(self.output_layer),
self.w_layer_one_to_layer_two.T) * sigmoid_derivative(self.layer_one))
self.w_input_layer_to_layer_one += np.dot(self.Dw_input_layer_to_layer_one, self.learning_rate)
self.w_layer_one_to_layer_two += np.dot(self.Dw_layer_one_to_layer_two, self.learning_rate)
self.w_layer_two_to_output_layer += np.dot(self.Dw_layer_two_to_output_layer, self.learning_rate)
def drawImageFromOutputs(self):
image = np.zeros((self.init_output_layers_res[0], self.init_output_layers_res[1], 3), dtype=np.float64)
count = 0
for height in range(self.init_output_layers_res[0]):
for width in range(self.init_output_layers_res[1]):
image[height][width] = [
self.output_layer[count][0] * 255, self.output_layer[count+1][0] * 255,
self.output_layer[count+2][0] * 255]
# print(image[height][width])
count += 3
if self.run_mode == MODE_TRAINING:
file_dir = r'./brain/memory/{}/'.format(self.training_image_name[:len(self.training_image_name) - 4])
file_name = r'images/{}-{}.png'.format(self.training_image_name[:len(self.training_image_name) - 4],
format(strftime("%Y_%m_%d-%H_%M_%S")))
try:
os.mkdir(file_dir)
except:
pass
else:
file_dir = r'./generated_images/'
file_name = r'{}.png'.format(strftime("%Y_%m_%d-%H_%M_%S"))
window_name = r'{}{}'.format(file_dir, file_name)
print(window_name)
cv2.imwrite(window_name, image)
# print("Could not write image.")
def generate_bias(self):
print("Generating Bias")
self.layer_one_bias = np.random.rand(1, self.input_layer.shape[1])
self.layer_two_bias = np.random.rand(1, self.input_layer.shape[1])
def generate_weights(self):
print("Generating Weights ")
self.w_input_layer_to_layer_one = np.random.rand(1, self.input_layer.shape[1])
self.w_layer_one_to_layer_two = np.random.rand(self.input_layer.shape[1], 1)
self.w_layer_two_to_output_layer = np.random.rand(self.input_layer.shape[1], 1)
def processTrainingImage(self, image):
#print("Processing Image Into Inputs")
self.training_image_name = image
self.training_image = cv2.imread(f"brain/training_images/{image}")
(height, width) = self.training_image.shape[:2]
inputsData = np.zeros((height*width*3, 1))
count = 0
for h in range(height):
for w in range(width):
(b, g, r) = self.training_image[h, w]
inputsData[count] = r / 255
inputsData[count+1] = g / 255
inputsData[count+2] = b / 255
count += 3
self.input_layer = np.array(inputsData)
#deb(self.input_layer.shape)
self.output_layer = np.zeros((len(self.input_layer), 1), dtype=np.float)
self.output_target = np.array(inputsData)
self.init_output_layers_res = [height, width]
def input_to_binary(self, inputsData):
input_list = []
for data in range(len(inputsData)):
for bit in inputsData[data]:
n1_bytes = bytearray(bit, "utf8")
n1_bin = bin(n1_bytes[0])[2:]
for b in n1_bin:
input_list.append(float(b))
bin_array = np.array(input_list)
return bin_array
MODE_TRAINING = 0
MODE_GENERATING = 1
m = mAiV2(MODE_TRAINING)
m.processTrainingImage("Borne_arcade_pixel.png")
#m.generate_layers()
m.generate_weights()
m.generate_bias()
# m.process_forward()
# m.process_backward()
for i in range(10000000): # trains the NN 1,000 times
if i % 10000 == 0:
print("for iteration # " + str(i) + "\n")
print("Input : \n" + str(m.input_layer))
print("Actual Output: \n" + str(m.output_target))
print("Predicted Output: \n" + str(m.process_forward()))
print("Loss: \n" + str(np.mean(np.square(m.output_target - m.process_forward())))) # mean sum squared loss
print("\n")
m.drawImageFromOutputs()
# d = np.array(NN.weights1).shape(5,5)
# image_list.append(np.array(NN.weights1).shape(5,5))
m.train()