- * 順方向演算を行います。\r
- * </p>\r
- * \r
- * @param input\r
- * 入力データ。\r
- * @return 演算結果。\r
- */\r
- public double[] forwardNeuralNet(double[] input) {\r
- double[] out = new double[SimpleNNApplet.OUTPUT];\r
- double[] hidden = new double[SimpleNNApplet.HIDDEN];\r
-\r
- // 隠れ層出力の計算\r
- for (int j = 0; j < SimpleNNApplet.HIDDEN; j++) {\r
- hidden[j] = -this.thresholdHidden[j];\r
- for (int i = 0; i < SimpleNNApplet.INPUT; i++) {\r
- hidden[j] += input[i] * this.weightInHidden[i][j];\r
- }\r
- this.hiddenOut[j] = this.sigmoid(hidden[j]);\r
- }\r
-\r
- // 出力層出力の計算\r
- for (int k = 0; k < SimpleNNApplet.OUTPUT; k++) {\r
- out[k] = -this.thresholdOut[k];\r
- for (int j = 0; j < SimpleNNApplet.HIDDEN; j++) {\r
- out[k] += this.hiddenOut[j] * this.weightHiddenOut[j][k];\r
- }\r
- out[k] = this.sigmoid(out[k]);\r
- }\r
-\r
- return out;\r
- }\r
-\r
- /**\r
- * <p>\r
- * 逆方向演算を行います。\r
- * </p>\r
- * \r
- * @param output\r
- * 順方向演算の結果。\r
- * @param teach\r
- * 教師信号。\r
- */\r
- public void backwardNeuralNet(double[] output, double[] teach) {\r
- int i;\r
- int j;\r
- int k;\r
-\r
- // 出力層の誤差\r
- double[] outputError = new double[SimpleNNApplet.OUTPUT];\r
- // 隠れ層の誤差\r
- double[] hiddenError = new double[SimpleNNApplet.HIDDEN];\r
- double tempError;\r
-\r
- // 出力層の誤差の計算\r
- for (k = 0; k < SimpleNNApplet.OUTPUT; k++) {\r
- outputError[k] = (teach[k] - output[k]) * output[k] * (1.0 - output[k]);\r
- }\r
-\r
- // 隠れ層の誤差の計算\r
- for (j = 0; j < SimpleNNApplet.HIDDEN; j++) {\r
- tempError = 0;\r
- for (k = 0; k < SimpleNNApplet.OUTPUT; k++) {\r
- tempError += outputError[k] * this.weightHiddenOut[j][k];\r
- }\r
- hiddenError[j] = this.hiddenOut[j] * (1.0 - this.hiddenOut[j]) * tempError;\r
- }\r
-\r
- // 重みの補正\r
- for (k = 0; k < SimpleNNApplet.OUTPUT; k++) {\r
- for (j = 0; j < SimpleNNApplet.HIDDEN; j++) {\r
- this.weightHiddenOut[j][k] += SimpleNNApplet.ALPHA * outputError[k] * this.hiddenOut[j];\r
- }\r
- }\r
- for (j = 0; j < SimpleNNApplet.HIDDEN; j++) {\r
- for (i = 0; i < SimpleNNApplet.INPUT; i++) {\r
- this.weightInHidden[i][j] += SimpleNNApplet.ALPHA * hiddenError[j] * this.sampleIn[i];\r
- }\r
- }\r
-\r
- // 閾値の補正\r
- for (k = 0; k < SimpleNNApplet.OUTPUT; k++) {\r
- this.thresholdOut[k] -= SimpleNNApplet.ALPHA * outputError[k];\r
- }\r
- for (j = 0; j < SimpleNNApplet.HIDDEN; j++) {\r
- this.thresholdHidden[j] -= SimpleNNApplet.ALPHA * hiddenError[j];\r
- }\r
- }\r
-\r
- /**\r
- * <p>\r
- * ニューラル・ネットワークの状態(閾値、重み)を初期化します。\r
- * </p>\r
- */\r
- public void initNetwork() {\r
- // TODO ちゃんとランダムに初期化する。\r
- try {\r
- BufferedReader reader = new BufferedReader(new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream("random.txt")));\r
- try {\r
- for (int j = 0; j < SimpleNNApplet.HIDDEN; j++) {\r
- this.thresholdHidden[j] = Double.parseDouble(reader.readLine()) - SimpleNNApplet.VALUE_HALF;\r
- for (int i = 0; i < SimpleNNApplet.INPUT; i++) {\r
- this.weightInHidden[i][j] = Double.parseDouble(reader.readLine()) - SimpleNNApplet.VALUE_HALF;\r
- }\r
- }\r
- for (int k = 0; k < SimpleNNApplet.OUTPUT; k++) {\r
- this.thresholdOut[k] = Double.parseDouble(reader.readLine()) - SimpleNNApplet.VALUE_HALF;\r
- for (int j = 0; j < SimpleNNApplet.HIDDEN; j++) {\r
- this.weightHiddenOut[j][k] = Double.parseDouble(reader.readLine()) - SimpleNNApplet.VALUE_HALF;\r
- }\r
- }\r
- } finally {\r
- reader.close();\r
- }\r
- } catch (IOException e) {\r
- e.printStackTrace();\r
- }\r
- }\r
-\r
- /**\r
- * <p>\r
- * 順方向演算の結果と教師信号とのずれを表す二乗誤差を算出します。\r
- * </p>\r
- * \r
- * @param output\r
- * 順方向演算の結果。\r
- * @param teach\r
- * 教師信号。\r
- * @return 二乗誤差。\r
- */\r
- public double calcError(double[] output, double[] teach) {\r
- double error = 0;\r
-\r
- for (int i = 0; i < output.length; i++) {\r
- error += (teach[i] - output[i]) * (teach[i] - output[i]);\r
- }\r
-\r
- return error;\r
- }\r
-\r
- /**\r
- * <p>\r
- * シグモイド関数です。\r
- * </p>\r
- * \r
- * @param x\r
- * 引数。\r
- * @return 計算結果。\r
- */\r
- public double sigmoid(double x) {\r
- return 1.0 / (1.0 + Math.exp(-SimpleNNApplet.BETA * x));\r
- }\r
-\r
- /**\r
- * <p>\r