/** * Copyright (C) 2017 Jan Schäfer (jansch@users.sourceforge.net) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jskat.ai.nn.util; /** * Holds information about the topology of a neural network */ public class NetworkTopology { private final int inputSignals; private final int outputSignals; private final int[] hiddenLayerNeurons; /** * Constructor * * @param inputs * Number of input neurons * @param outputs * Number of output neurons * @param hiddenLayerNeurons * Number of neurons in every hidden layer */ public NetworkTopology(int inputs, int[] hiddenLayerNeurons, int outputs) { this.inputSignals = inputs; this.hiddenLayerNeurons = hiddenLayerNeurons; this.outputSignals = outputs; } /** * Gets the number of input neurons * * @return Number of input neurons */ int getInputNeuronCount() { return this.inputSignals; } /** * Gets the number of hidden layers * * @return Number of hidden layers */ int getHiddenLayerCount() { return hiddenLayerNeurons.length; } /** * Gets the number of hidden neurons in a hidden layer * * @param layerID * ID of the hidden layer * @return Number of hidden neurons in the hidden layer */ int getHiddenNeuronCount(int layerID) { if (layerID < 0) { throw new IllegalArgumentException( "Layer must be greater or equals 0."); //$NON-NLS-1$ } if (layerID >= hiddenLayerNeurons.length) { throw new IllegalArgumentException( "Network has only " + hiddenLayerNeurons.length + " hidden layers."); //$NON-NLS-1$ //$NON-NLS-2$ } return this.hiddenLayerNeurons[layerID]; } /** * Gets the number of output neurons * * @return Number of output neurons */ int getOutputNeuronCount() { return this.outputSignals; } /** * @see Object#toString() */ @Override public String toString() { StringBuffer result = new StringBuffer(); // result.append("<topo>\n"); // result.append("\t<numberoflayers>").append(this.hiddenLayers + // 2).append("</numberoflayers>\n"); // result.append("\t<layer id=\"0\" type=\"input\">\n"); // result.append("\t\t<numberofneurons>").append(getInputNeuronCount()).append("</numberofneurons>\n"); // result.append("\t</layer>\n"); // for (int i = 0; i < this.hiddenLayers; i++) { // // result.append("\t<layer id=\"" + (i + 1) + "\" type=\"hidden\">\n"); // result.append("\t\t<numberofneurons>").append(getHiddenNeuronCount(i)).append("</numberofneurons>\n"); // } // result.append("\t</layer>\n"); // result.append("\t<layer id=\"" + (this.hiddenLayers + 1) + // "\" type=\"output\">\n"); // result.append("\t\t<numberofneurons>").append(getOutputNeuronCount()).append("</numberofneurons>\n"); // result.append("\t</layer>\n"); // result.append("</topo>\n"); result.append("input\n"); //$NON-NLS-1$ result.append(getInputNeuronCount()).append('\n'); result.append("hidden ").append(this.hiddenLayerNeurons.length).append('\n'); //$NON-NLS-1$ for (int i = 0; i < this.hiddenLayerNeurons.length; i++) { result.append(getHiddenNeuronCount(i)).append('\n'); } result.append("output\n"); //$NON-NLS-1$ result.append(getOutputNeuronCount()).append('\n'); return result.toString(); } int getMaxWeightsForLayers() { int result = 0; int previousNodes = getInputNeuronCount(); for (int i = 1; i < getLayerCount(); i++) { int currentNodes = getNeuronCount(i); // all previous nodes are connected to all current nodes result = Math.max(result, previousNodes * currentNodes); previousNodes = currentNodes; } return result; } int getLayerCount() { return getHiddenLayerCount() + 2; } int getLastLayer() { return getLayerCount() - 1; } int getNeuronCount(int layer) { int result = 0; if (layer == 0) { result = getInputNeuronCount(); } else if (layer == getLastLayer()) { result = getOutputNeuronCount(); } else { result = getHiddenNeuronCount(layer - 1); } return result; } int getMaxNodesForLayers() { int result = 0; for (int i = 0; i < getLayerCount(); i++) { result = Math.max(result, getNeuronCount(i)); } return result; } }