/// <summary> /// 全結合 /// </summary> /// <param name="input"></param> /// <param name="outputDim"></param> /// <param name="withBias"></param> /// <param name="device"></param> /// <returns></returns> public static Function Dense(this Function function, int outputDim, bool withBias = true, string name = "") { Variable input = (Variable)function; if (input.Shape.Rank != 1) { // 一次元でないとき、一次元に並び替える int newDim = input.Shape.Dimensions.Aggregate((d1, d2) => d1 * d2); input = CNTKLib.Reshape(input, new int[] { newDim }); } var weightParam = new CNTK.Parameter( new int[] { outputDim, input.Shape.TotalSize }, CNTK.DataType.Float, CNTK.CNTKLib.GlorotUniformInitializer( CNTK.CNTKLib.DefaultParamInitScale, CNTK.CNTKLib.SentinelValueForInferParamInitRank, CNTK.CNTKLib.SentinelValueForInferParamInitRank, 1), //CNTK.CNTKLib.XavierInitializer(), _device, name + "_w" ); // input * weightParam + biasParam if (withBias == true) { var biasParam = new Parameter(new int[] { outputDim }, DataType.Float, 0, _device, name + "_b"); return(CNTKLib.Plus(CNTKLib.Times(weightParam, input, name + "_times"), biasParam, name)); } else { return(CNTKLib.Times(weightParam, input, name)); } }
C.Function create_capsule_layer(C.Function inputs, int num_capsule, int dim_capsule, int routings, string name) { var inputs_shape = inputs.Output.Shape.Dimensions; var input_num_capsule = inputs_shape[0]; var input_dim_capsule = inputs_shape[1]; var W = new C.Parameter( new int[] { num_capsule, dim_capsule, input_num_capsule, input_dim_capsule }, C.DataType.Float, CC.GlorotUniformInitializer(), computeDevice, name: "W"); inputs = CC.Reshape(inputs, new int[] { 1, 1, input_num_capsule, input_dim_capsule }); // [1, 1, 1152, 8]) var inputs_hat = CC.ElementTimes(W, inputs); inputs_hat = CC.ReduceSum(inputs_hat, new C.Axis(3)); inputs_hat = CC.Squeeze(inputs_hat); C.Function outputs = null; var zeros = new C.Constant(new int[] { num_capsule, 1, input_num_capsule }, C.DataType.Float, 0, computeDevice); var b = CC.Combine(new C.VariableVector() { zeros }); for (int i = 0; i < routings; i++) { var c = CC.Softmax(b, new C.Axis(0)); var batch_dot_result = CC.ElementTimes(c, inputs_hat); batch_dot_result = CC.ReduceSum(batch_dot_result, new C.Axis(2)); batch_dot_result = CC.Squeeze(batch_dot_result); outputs = squash(batch_dot_result, name: $"squashed_{i}", axis: 1); if (i < (routings - 1)) { outputs = CC.Reshape(outputs, new int[] { num_capsule, dim_capsule, 1 }); batch_dot_result = CC.ElementTimes(outputs, inputs_hat); batch_dot_result = CC.ReduceSum(batch_dot_result, new C.Axis(1)); b = CC.Plus(b, batch_dot_result); } } outputs = CC.Combine(new C.VariableVector() { outputs }, name); return(outputs); }
internal Parameter(CNTK.Parameter constant) : base(constant) { UnderlyingParameter = constant; }