我正在使用(ENCOG library)来创建和训练神经网络。它必须从建模字典中找到真实的故障向量(它有12个数字 - 如矢量=故障的特征)(它有70个故障,在12个频率上识别)。
在NN中,我有输入(12个神经元=一个输入故障矢量的len),隐藏(14个神经元= 2 *输出神经元)和输出(7个神经元 - 通过'0 \ 1'70个故障识别)层。
这是NN的代码(在C#上):
public static double[][] XORInput =
{
new double[] { 1, 1, 1, 1,1,1,1,2,2,2,2,2 },
new double[] { 5, 5, 5, 5,5,5,5,6,6,7,7,7 },
new double[] { 6, 6,6,6,6,6,5,5,5,1,2,3 },
new double[] { 3, 3, 3, 3,3,3,3,3,2,2,1,1 } ,
new double[] { 1, 1, 2, 2,2,3,3,3,3,3,3,3 },
new double[] { 1, 4, 2, 7,2,5,6,7,8,8,8,8 },
new double[] { 2, 3, 3, 3,3,3,3,3,3,3,2,2 },
new double[] { 7,7, 7, 7,7,8,8,8,7,7,7,7 },
new double[] { 6, 7, 7, 8,8,8,8,8,8,7,7,6 },
new double[] { 3, 3, 3, 4 ,4,4,4,4,4,3,3,3 },
new double[] { 1, 1, 1, 1,1,2,2,2,2,2,2,2 },
new double[] { 5, 5, 5, 5,5,6,6,6,6,6,6,7 },
new double[] { 1,2,3,4,5,6,7,8,1,2,3,1 },
new double[] { 1, 1, 1, 1,1,1,1,1,1,2,4,1 },
new double[] { 1, 1, 1, 1,1,1,1,1,1,1,1,1 },
new double[] { 5, 5, 5,5,5,5,5,5,5,5,5,5 },
new double[] {7, 8, 8, 8,8,7,6,4,1,2,2,2 },
new double[] { 2, 3, 3, 3,3,4,4,4,4,3,3,3 },
new double[] { 8, 8,8, 8,8,5,6,7,8,8,8,8 },
new double[] { 5, 5, 5, 5,5,6,8,6,1,1,1,1 },
new double[] { 1, 1, 1, 1,1,1,1,4,4,6,3,5 },
new double[] { 2, 2, 2, 2,2,2,2,2,3,3,3,3 },
new double[] { 6, 6, 6, 6,7,7,7,7,7,8,8,8 },
new double[] { 1, 16, 2, 6,71,72,73,27,74,81,81,58 },
new double[] { 2, 36, 3, 67,87,7,17,27,37,2,1,1 },
new double[] { 3, 46, 4, 8,4,5,6,7,22,8,18,2 },
new double[] { 4, 56, 12, 9,1,2,4,12,4,44,1,8 },
new double[] { 5, 66, 5, 6,17,4,5,11,5,7,8,9 },
new double[] { 6, 86, 6, 6, 10,2,5,8,1,3,5,1 },
new double[] { 66, 16, 14, 11,1,1,1,2,1,4,1,6 },
new double[] { 67, 6,11 , 16,2,2,2,7,21,2,1,9 },
new double[] { 7, 6, 10, 62,12,3,4,54,1,1,3,3 },
new double[] { 8, 16,9, 6,17,7,1,2,7,5,1,4 },
new double[] { 9, 26,11, 6,73,6,2,3,4,5,5,2 },
new double[] { 61, 21, 85, 61,5,2,5,1,6,3,4,5 },
new double[] { 31, 1, 11, 1,1,1,1,2,2,2,2,2 },
new double[] { 15, 5, 15, 5,5,5,5,6,6,7,7,7 },
new double[] { 36, 6,16,6,6,6,5,5,5,1,2,3 },
new double[] { 53, 3, 13, 3,3,3,3,3,2,2,1,1 } ,
new double[] { 71, 1, 22, 2,2,3,3,3,3,3,3,3 },
new double[] { 81, 4, 21, 7,2,5,6,7,8,8,8,8 },
new double[] { 12, 3, 13, 3,3,3,3,3,3,3,2,2 },
new double[] { 97,7, 71, 7,7,8,8,8,7,7,7,7 },
new double[] { 5, 7, 17, 8,8,8,8,8,8,7,7,6 },
new double[] { 13, 3, 13, 4,4,4,4,4,4,3,3,3 },
new double[] { 11, 1, 11, 1,1,2,2,2,2,2,2,2 },
new double[] { 55, 5, 51, 5,5,6,6,6,6,6,6,7 },
new double[] { 16,2,19,4,5,6,7,8,1,2,3,1 },
new double[] { 17, 1, 11, 1,1,1,1,1,1,2,4,1 },
new double[] { 19, 1, 21, 1,1,1,1,1,1,1,1,1 },
new double[] { 25, 5, 25,5,5,5,5,5,5,5,5,5 },
new double[] {27, 8, 28, 8,8,7,6,4,1,2,2,2 },
new double[] { 22, 3, 23, 3,3,3,3,3,3,2,1,7 },
new double[] { 32, 3, 27, 3,3,4,4,4,4,3,3,3 },
new double[] { 18, 8,2, 8,8,5,6,7,8,8,8,8 },
new double[] { 31, 1, 4, 1,1,1,1,4,4,6,3,5 },
new double[] { 23, 2, 6, 2,2,2,2,2,3,3,3,3 },
new double[] { 36, 6, 16, 6,7,7,7,7,7,8,8,8 },
new double[] { 31, 16, 5, 6,71,72,73,27,74,81,81,58 },
new double[] { 12, 36, 14, 67,87,7,17,27,37,2,1,1 },
new double[] { 31, 46, 41, 8,4,5,6,7,22,8,18,2 },
new double[] { 14, 56, 1, 9,1,2,4,12,4,44,1,8 },
new double[] { 15, 66, 59, 6,17,4,5,11,5,7,8,9 },
new double[] { 16, 86, 16, 6, 10,2,5,8,1,3,5,1 },
new double[] { 16, 16, 10, 11,1,1,1,2,1,4,1,6 },
new double[] { 17, 6,114, 16,2,2,2,7,21,2,1,9 },
new double[] { 71, 6, 1, 62,12,3,4,54,1,1,3,3 },
new double[] { 18, 16,19, 6,17,7,1,2,7,5,1,4 },
new double[] { 19, 26,1, 6,73,6,2,3,4,5,5,2 },
new double[] { 6, 21, 5, 61,5,2,5,1,6,3,4,5 } //70
};
/// <summary>
/// Array of numbers, which equal to squares of two
/// </summary>
static int[] powOfTwo = {2, 4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536 };
private static void Main(string[] args)
{
double[][] XORIdeal = computeOutputVector(XORInput);
// normalizing input data
double[][] input = normalizeData(XORInput);
// create a neural network, without using a factory
var network = new BasicNetwork();
network.AddLayer(new BasicLayer(null, true, 12));
network.AddLayer(new BasicLayer(new ActivationSigmoid(), true, 14));
network.AddLayer(new BasicLayer(new ActivationSigmoid(), false, 7));
network.Structure.FinalizeStructure();
network.Reset();
// create training data
IMLDataSet trainingSet = new BasicMLDataSet(input, XORIdeal);
//IMLDataSet trainingSet = new BasicMLDataSet(XORInput, XORIdeal);
// train the neural network
//IMLTrain train = new ResilientPropagation(network, trainingSet);
//var train = new Backpropagation ( network , trainingSet , 0.3 , 0.7 ) ;
var train = new Backpropagation(network, trainingSet, 0.2, 0.15); // speed and influence of backpropogation algorithm
int epoch = 1;
do
{
train.Iteration();
Console.WriteLine(@"Epoch #" + epoch + @" Error:" + train.Error);
epoch++;
} while (train.Error > 0.05 && epoch < 2000);
train.FinishTraining();
// test the neural network
Console.WriteLine(@"Neural Network Results:");
double[] data = new double[] { 1, 1, 1, 1,1,1,1,2,2,2,2,2 }; //{ 5.1, 5.4, 5.5, 5.5, 5.8, 5.6, 5.6, 6.5, 6.6, 7.1, 7.1, 7.1 }; // 0000001
double[] realSignature22 = new double[] { 6.21, 4.2, 6.6, 6.6, 6.6, 5.56, 6.5, 7, 7, 6.89, 6.8, 8 }; // 0010110
double[] realSignature34 = new double[] { 58, 24, 90, 55, 4.5, 1.82, 5.4, 1.1, 6.4, 3.1, 3.4, 5.3 }; // 0100010
IMLData example1 = new BasicMLData(normilizeRow(data));
IMLData output1 = network.Compute(example1);
Console.WriteLine("\nactual : 0 0 0 0 0 0 0 = #0 ");
findNumber(output1);
IMLData example = new BasicMLData(normilizeRow(realSignature34));
IMLData output = network.Compute(example);
Console.WriteLine("\nactual : 0 1 0 0 0 1 0 = #34 ");
findNumber(output);
IMLData example2 = new BasicMLData(normilizeRow(realSignature22));
IMLData output2 = network.Compute(example2);
Console.WriteLine("\nactual : 0 0 1 0 1 1 0 = #22 ");
findNumber(output2);
EncogFramework.Instance.Shutdown();
}
/// <summary>
/// Returns degree of two which cowers number of mistakes in the input vector
/// </summary>
/// <param name="XORInput"></param>
/// <returns></returns>
static int calcSizeOfOutputVector(double[][] XORInput)
{
int size = 0;
int len = XORInput.GetLength(0);
foreach (int number in powOfTwo)
{
size++;
if (len <= number) return size;
}
return -1;
}
static double[][] computeOutputVector(double[][] XORInput)
{
double[][] output;
int sizeOfOut = calcSizeOfOutputVector(XORInput);
int numOfFaults = XORInput.GetLength(0);
output = new double[numOfFaults][];
// convert decimal number into corresponding array from 0 and 1 (equal to decimal number)
for (int i = 0; i < numOfFaults; i++)
{
output[i] = new double[sizeOfOut];
convertDecToByteAndSaveInDoubleArray(output[i], i);
}
return output;
}
static double[] convertDecToByteAndSaveInDoubleArray(double[] outArray, int number ){
// convert number into binary representation
string binaryCode = Convert.ToString(number, 2);
int size = outArray.GetLength(0);
// Initially fill with zeros
for (int i = 0; i < size; i++) outArray[i] = 0;
//
for (int i = 0; i < binaryCode.Length; i++)
{
double d = Double.Parse(binaryCode.Substring(binaryCode.Length - i - 1, 1));
outArray[size - 1 - i] = d;
}
return outArray;
}
static void printOutputResults(IMLData output){
Console.WriteLine("\nFrom NN ");
for (int i = 0; i < output.Count; i++ )
Console.Write(" " + output[i] + " " );
}
static int[] findNumber(IMLData output)
{
int len = output.Count;
// Round to 0 and 1 numbers, which is received from NN
int[] outAr = new int[len];
for (int i = 0; i < output.Count; i++)
{
outAr[i] = (int)Math.Round(output[i]);
}
// Display output vectors
// Bug for number 1 and length 7 in the input vector looks like : 0[0] 0[1] 0[2] 0[3] 0[4] 0[5] 1[6] (in binary system) = 1 (in decimal system)
Console.WriteLine("\nFrom NN ");
for (int i = 0; i < len; i++)
Console.Write(" " + outAr[i] + " ");
// Convert binary vector into decimal
Console.WriteLine("\nFrom NN (converted number)" + convertBinArrayToDecNumber(outAr));
return outAr;
}
static int convertBinArrayToDecNumber(int[] binaryArray)
{
int n = 0;
int maxIndex = binaryArray.Length - 1;
for (int i = maxIndex; i >= 0; i--)
n += (int)Math.Pow(2, maxIndex - i) * binaryArray[i];
return n;
}
static double[][] normalizeData(double[][] data)
{
int numOfRows = data.Length;
int lenOfRow = data[0].GetLength(0);
double[][] result = new double[numOfRows][];
for (int i = 0; i < numOfRows; i++)
result[i] = normilizeRow(data[i]);
return result;
}
static double[] normilizeRow(double[] row)
{
int lenOfRow = row.GetLength(0);
double[] result = new double[lenOfRow];
for (int i = 0; i < lenOfRow; i++) result[i] = 0;
double N = 0;
foreach (double num in row) N += num * num;
if (N != 0) {
for (int j = 0; j < lenOfRow; j++)
{
result[j] = (row[j] / Math.Sqrt(N));
}
}
return result;
}
我尝试通过backpropogation编辑训练参数,但几乎每次我都有很高的训练水平。
但此代码中最大的问题是结果。每次运行代码都有不同的(而不是正确的!!!)结果。例如:
actual : 0 0 0 0 0 0 0 = #0
From NN
0 0 0 0 0 0 1
From NN (converted number)1
actual : 0 1 0 0 0 1 0 = #34
From NN
0 1 0 0 0 1 0
From NN (converted number)34
actual : 0 0 1 0 1 1 0 = #22
From NN
0 0 0 0 0 1 0
From NN (converted number)2
或另一个:
Neural Network Results:
actual : 0 0 0 0 0 0 0 = #0
From NN
0 0 0 0 1 0 1
From NN (converted number)5
actual : 0 1 0 0 0 1 0 = #34
From NN
0 1 0 0 0 1 0
From NN (converted number)34
actual : 0 0 1 0 1 1 0 = #22
From NN
0 0 0 1 1 1 1
From NN (converted number)15
任何人都可以告诉我:
1)如何更有效地培训网络
2)为什么NN无法正确识别像'{1,1,1,1,1,1,2,2,2,2,2}'这样的行(在列车数据中)?
// --------------------------------------------- ----------------------
我尝试用Encog函数来规范化数据。代码:
public static void readCSVFileToNN(){
int numOfCol = 12;
// Define the format of the data file.
// This area will change, depending on the columns and
// format of the file that you are trying to model.
IVersatileDataSource source = new CSVDataSource("c:\\test.txt", false,
CSVFormat.DecimalPoint);
var data = new VersatileMLDataSet(source);
for (int i = 0; i < numOfCol; i++ )
data.DefineSourceColumn("freq#" +i , i, ColumnType.Nominal);
// Define the column that we are trying to predict.
ColumnDefinition outputColumn = data.DefineSourceColumn("faultNumbers", 12,
ColumnType.Nominal);
// Analyze the data, determine the min/max/mean/sd of every column.
data.Analyze();
// Map the prediction column to the output of the model, and all
// other columns to the input.
data.DefineSingleOutputOthersInput(outputColumn);
// Create feedforward neural network as the model type. MLMethodFactory.TYPE_FEEDFORWARD.
// You could also other model types, such as:
// MLMethodFactory.SVM: Support Vector Machine (SVM)
// MLMethodFactory.TYPE_RBFNETWORK: RBF Neural Network
// MLMethodFactor.TYPE_NEAT: NEAT Neural Network
// MLMethodFactor.TYPE_PNN: Probabilistic Neural Network
var model = new EncogModel(data);
model.SelectMethod(data, MLMethodFactory.TypeFeedforward);
// Send any output to the console.
model.Report = new ConsoleStatusReportable();
// Now normalize the data. Encog will automatically determine the correct normalization
// type based on the model you chose in the last step.
data.Normalize();
// Hold back some data for a final validation.
// Shuffle the data into a random ordering.
// Use a seed of 1001 so that we always use the same holdback and will get more consistent results.
model.HoldBackValidation(0.3, true, 1001);
// Choose whatever is the default training type for this model.
model.SelectTrainingType(data);
// Use a 5-fold cross-validated train. Return the best method found.
var bestMethod = (IMLRegression)model.Crossvalidate(2, true);
// Display the training and validation errors.
Console.WriteLine(@"Training error: " + model.CalculateError(bestMethod, model.TrainingDataset));
Console.WriteLine(@"Validation error: " + model.CalculateError(bestMethod, model.ValidationDataset));
// Display our normalization parameters.
NormalizationHelper helper = data.NormHelper;
Console.WriteLine(helper.ToString());
// Display the final model.
Console.WriteLine(@"Final model: " + bestMethod);
source.Close();
// test work of model on the example:
IMLData input = helper.AllocateInputVector();
var line = new String[numOfCol];
var result = new StringBuilder();
// в качестве примера возьмем сигнатуру [5,5,..,5] под номером 15
for (int i = 0; i < numOfCol; i++)
line[i] = 5.ToString();
String correct = 15.ToString();
// нормализуем входной вектор
helper.NormalizeInputVector(line, ((BasicMLData) input).Data, false);
// производим поиск по НС
IMLData output = bestMethod.Compute(input);
// выводим результат
String faultChosen = helper.DenormalizeOutputVectorToString(output)[0];
result.Append(line);
result.Append(" -> predicted: ");
result.Append(faultChosen);
result.Append("(correct: ");
result.Append(correct);
result.Append(")");
Console.WriteLine(result.ToString());
}
但结果仍然很糟糕。我做这个功能~10次,没有一个结果不正确
答案 0 :(得分:1)
您的问题是每行标准化与其他行无关。例如,第一行将是27处的每个值的除法,第二行将是394处的每个数字的除法。问题的另一个来源可能是您需要将每行独立规范化,但是所有行应根据某些规则进行归一化。然后,您应该为输入应用相同的规范化规则。我建议你看看Encog中的函数normalize。