public override _Tensor[] ForwardPass(_Tensor[] inputs) { results[0] = (NN_Utils.GEMM(kernel, inputs[0])) + bias; activationFunction.Activate(ref results[0]); return(results); }
/// <summary> /// Computes the probability of choosing an action given a stack of frames and the value function /// </summary> /// <param name="inputTensor"> /// Input tensor of shape HxWxM /// </param> public double[,] Predict(double[,,] inputTensor) { double[,,] dw_h_conv1 = NN_Utils.DepthWiseConv(inputTensor, W_DW_conv1, W_conv1_size[4]); double[,,] h_conv1 = NN_Utils.PointWiseConv(dw_h_conv1, PW_conv1); NN_Utils.ReLU(ref h_conv1); double[,,] dw_h_conv2 = NN_Utils.DepthWiseConv(h_conv1, W_DW_conv2, W_conv2_size[4]); double[,,] h_conv2 = NN_Utils.PointWiseConv(dw_h_conv2, PW_conv2); NN_Utils.ReLU(ref h_conv2); double[,] h_conv3_flat = NN_Utils.Flatten(h_conv2); double[,] h_fc1 = new double[1, W_fc1_size[1]]; double[,] action_output = new double[1, W_fc2_size[1]]; NN_Utils.GEMM(h_conv3_flat, W_fc_1, ref h_fc1); NN_Utils.ReLU(ref h_fc1); NN_Utils.GEMM(h_fc1, W_fc_2, ref action_output); NN_Utils.Softmax(ref action_output); Value_funtion = 0d; for (int i = 0; i < h_fc1.GetLength(0); i++) { for (int j = 0; j < h_fc1.GetLength(1); j++) { Value_funtion += h_fc1[i, j]; } } return(action_output); }