本文实例讲述了Python利用神经网络解决非线性回归问题。分享给大家供大家参考,具体如下:
问题描述
现在我们通常使用神经网络进行分类,但是有时我们也会进行回归分析。
如本文的问题:
我们知道一个生物体内的原始有毒物质的量,然后对这个生物体进行治疗,向其体内注射一个物质,过一段时间后重新测量这个生物体内有毒物质量的多少。
因此,问题中有两个输入,都是标量数据,分别为有毒物质的量和注射物质的量,一个输出,也就是注射治疗物质后一段时间生物体的有毒物质的量。
数据如下图:
其中Dose of Mycotoxins 就是有毒物质,Dose of QCT就是治疗的药物。
其中蓝色底纹的数字就是输出结果。
一些说明
由于本文是进行回归分析,所以最后一层不进行激活,而直接输出。
本文程序使用sigmoid函数进行激活。
本文程序要求程序有一定的可重复性,隐含层可以指定。
另外,注意到
本文将使用数据预处理,也就是将数据减去均值再除以方差,否则使用sigmoid将会导致梯度消失。
因为数据比较大,比如200,这时输入200,当sigmoid函数的梯度就是接近于0了。
与此同时,我们在每一次激活前都进行BN处理,也就是batch normalize,中文可以翻译成规范化。
否则也会导致梯度消失的问题。与预处理情况相同。
程序
程序包括两部分,一部分是模型框架,一个是训练模型
第一部分:
# coding=utf-8
import numpy as np
def basic_forard(x, w, b):
x = x.reshape(x.shape[0], -1)
out = np.dot(x, w) + b
cache = (x, w, b)
return out, cache
def basic_backward(dout, cache):
x, w, b = cache
dout = np.array(dout)
dx = np.dot(dout, w.T)
# dx = np.reshape(dx, x.shape)
# x = x.reshape(x.shape[0], -1)
dw = np.dot(x.T, dout)
db = np.reshape(np.sum(dout, axis=0), b.shape)
return dx, dw, db
def batchnorm_forward(x, gamma, beta, bn_param):
mode = bn_param['mode']
eps = bn_param.get('eps', 1e-5)
momentum = bn_param.get('momentum', 0.9)
N, D = x.shape
running_mean = bn_param.get('running_mean', np.zeros(D, dtype=x.dtype))
running_var = bn_param.get('running_var', np.zeros(D, dtype=x.dtype))
out, cache = None, None
if mode == 'train':
sample_mean = np.mean(x, axis=0)
sample_var = np.var(x, axis=0)
x_hat = (x - sample_mean) / (np.sqrt(sample_var + eps))
out = gamma * x_hat + beta
cache = (gamma, x, sample_mean, sample_var, eps, x_hat)
running_mean = momentum * running_mean + (1 - momentum) * sample_mean
running_var = momentum * running_var + (1 - momentum) * sample_var
elif mode == 'test':
scale = gamma / (np.sqrt(running_var + eps))
out = x * scale + (beta - running_mean * scale)
else:
raise ValueError('Invalid forward batchnorm mode "%s"' % mode)
bn_param['running_mean'] = running_mean
bn_param['running_var'] = running_var
return out, cache
def batchnorm_backward(dout, cache):
gamma, x, u_b, sigma_squared_b, eps, x_hat = cache
N = x.shape[0]
dx_1 = gamma * dout
dx_2_b = np.sum((x - u_b) * dx_1, axis=0)
dx_2_a = ((sigma_squared_b + eps) ** -0.5) * dx_1
dx_3_b = (-0.5) * ((sigma_squared_b + eps) ** -1.5) * dx_2_b
dx_4_b = dx_3_b * 1
dx_5_b = np.ones_like(x) / N * dx_4_b
dx_6_b = 2 * (x - u_b) * dx_5_b
dx_7_a = dx_6_b * 1 + dx_2_a * 1
dx_7_b = dx_6_b * 1 + dx_2_a * 1
dx_8_b = -1 * np.sum(dx_7_b, axis=0)
dx_9_b = np.ones_like(x) / N * dx_8_b
<