下面是我对具有1个输入层,两个隐藏层和1个输出层的神经网络的实现:
import breeze.linalg._
import breeze.math._
import breeze.numerics._
object NN extends App {
//Forward propogation
val x1 = DenseVector(1.0, 0.0, 1.0)
val y1 = DenseVector(1.0, 1.0, 1.0)
val theta1 = DenseMatrix((1.0, 1.0, 1.0), (1.0, 1.0, 0.0), (1.0, 0.0, 0.0));
val theta2 = DenseMatrix((1.0, 1.0, 1.0), (1.0, 1.0, 0.0), (1.0, 0.0, 0.0));
val theta3 = DenseMatrix((1.0, 1.0, 1.0), (1.0, 1.0, 0.0), (1.0, 0.0, 0.0));
val a1 = x1;
val z2 = theta1 * a1;
val a2 = (z2.map { x => 1 + sigmoid(x) })
val z3 = theta2 * a2;
val a3 = (z3.map { x => 1 + sigmoid(x) })
val z4 = theta3 * a3;
val a4 = (z4.map { x => 1 + sigmoid(x) })
//Back propagation
val errorLayer4 = a4 - DenseVector(1.0, 1.0, 1.0)
val errorLayer3 = (theta3.t * errorLayer4) :* (a3 :* (DenseVector(1.0, 1.0, 1.0) - a3))
val errorLayer2 = (theta2.t * errorLayer3) :* (a2 :* (DenseVector(1.0, 1.0, 1.0) - a2))
//Compute delta values
val delta1 = errorLayer2 * a2.t
val delta2 = errorLayer3 * a3.t
val delta3 = errorLayer4 * a4.t
//Gradient descent
val m = 1
val alpha = .0001
val x = DenseVector(1.0, 0.0, 1.0)
val y = DenseVector(1.0, 1.0, 1.0)
val pz1 = delta1 - (alpha / m) * (x.t * (delta1 * x - y))
val p1z1 = (sigmoid(delta1 * x)) + 1.0
println(p1z1);
val pz2 = delta2 - (alpha / m) * (x.t * (delta2 * x - y))
val p1z2 = (sigmoid(delta2 * p1z1)) + 1.0
println(p1z2);
val pz3 = delta3 - (alpha / m) * (x.t * (delta3 * x - y))
val p1z3 = (sigmoid(delta3 * p1z2)) + 1.0
println(p1z3);
}
该网络的输出是:
Jun 03, 2016 7:47:50 PM com.github.fommil.netlib.BLAS <clinit>
WARNING: Failed to load implementation from: com.github.fommil.netlib.NativeSystemBLAS
Jun 03, 2016 7:47:50 PM com.github.fommil.jni.JniLoader liberalLoad
INFO: successfully loaded C:\Users\Local\Temp\jniloader3606930058943197684netlib-native_ref-win-x86_64.dll
DenseVector(2.0, 2.0, 1.9999999999946196)
DenseVector(1.0, 1.0, 1.0000000064265646)
DenseVector(1.9971047766732295, 1.9968279599465841, 1.9942769808711798)
我使用的是单个训练示例101,输出值为111。
当预测值应为1,1,1时,给定1,0,1
的预测值为1.9,1.9,1.9
。
我认为我是如何计算偏差的sigmoid是不正确的,如果在sigmoid计算图层后添加偏差+1值,换句话说使用{ x => sigmoid(x+1) }
而不是{ x => 1 + sigmoid(x) }
?
答案 0 :(得分:1)
感知器式神经元的输出是sigmoid(sum(xi * wi)),其中偏置输入x0
为1,但重量不一定是1.你绝对不会把sigmoid外面的1加起来,但你也不要把它加在里面。你需要一个体重。所以它应该等同于
sigmoid(w0 + w1*x1 + w2*x2 + ...)