From 0838a692740c501a21d6d8f1def87e172db9338e Mon Sep 17 00:00:00 2001 From: Zhongkai Fu Date: Wed, 23 Dec 2015 22:52:13 -0800 Subject: [PATCH] #1. Improve logger #2. Using error token ratio to verify validated set performance --- ConvertCorpus/ConvertCorpus.csproj | 3 + ConvertCorpus/Program.cs | 3 +- RNNSharp/BiRNN.cs | 3 +- RNNSharp/Featurizer.cs | 17 +++-- RNNSharp/LSTMRNN.cs | 5 +- RNNSharp/ModelSetting.cs | 25 +++--- RNNSharp/RNN.cs | 36 ++++----- RNNSharp/RNNDecoder.cs | 9 ++- RNNSharp/RNNEncoder.cs | 33 ++++---- RNNSharp/Sentence.cs | 3 +- RNNSharp/Sequence.cs | 3 +- RNNSharp/SimpleRNN.cs | 5 +- RNNSharp/TemplateFeaturizer.cs | 2 +- RNNSharpConsole/Program.cs | 101 +++++++++++++------------ RNNSharpConsole/RNNSharpConsole.csproj | 4 + TFeatureBin/Program.cs | 8 +- dll/AdvUtils.dll | Bin 64000 -> 62464 bytes 17 files changed, 139 insertions(+), 121 deletions(-) diff --git a/ConvertCorpus/ConvertCorpus.csproj b/ConvertCorpus/ConvertCorpus.csproj index c33a002..a87f297 100644 --- a/ConvertCorpus/ConvertCorpus.csproj +++ b/ConvertCorpus/ConvertCorpus.csproj @@ -32,6 +32,9 @@ 4 + + ..\dll\AdvUtils.dll + diff --git a/ConvertCorpus/Program.cs b/ConvertCorpus/Program.cs index edfd5ea..b5bdfde 100644 --- a/ConvertCorpus/Program.cs +++ b/ConvertCorpus/Program.cs @@ -4,6 +4,7 @@ using System.Text; using System.Threading.Tasks; using System.IO; +using AdvUtils; namespace ConvertCorpus { @@ -18,7 +19,7 @@ static int ArgPos(string str, string[] args) { if (a == args.Length - 1) { - Console.WriteLine("Argument missing for {0}", str); + Logger.WriteLine(Logger.Level.info, "Argument missing for {0}", str); return -1; } return a; diff --git a/RNNSharp/BiRNN.cs b/RNNSharp/BiRNN.cs index 06c271e..b73f708 100644 --- a/RNNSharp/BiRNN.cs +++ b/RNNSharp/BiRNN.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using AdvUtils; namespace RNNSharp { @@ -432,7 +433,7 @@ public override void saveNetBin(string filename) public override void loadNetBin(string filename) { - Console.WriteLine("Loading bi-directional model: {0}", filename); + Logger.WriteLine(Logger.Level.info, "Loading bi-directional model: {0}", filename); forwardRNN.loadNetBin(filename + ".forward"); backwardRNN.loadNetBin(filename + ".backward"); diff --git a/RNNSharp/Featurizer.cs b/RNNSharp/Featurizer.cs index a9ac2ce..73337cf 100644 --- a/RNNSharp/Featurizer.cs +++ b/RNNSharp/Featurizer.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using System.IO; using Txt2Vec; +using AdvUtils; namespace RNNSharp { @@ -68,25 +69,25 @@ public void LoadFeatureConfigFromFile(string strFileName) string strValue = kv[1].Trim().ToLower(); if (strKey == WORDEMBEDDING_FILENAME) { - Console.WriteLine("Loading word embedding feature set..."); + Logger.WriteLine(Logger.Level.info, "Loading word embedding feature set..."); m_WordEmbedding = new WordEMWrapFeaturizer(strValue); continue; } else if (strKey == TFEATURE_FILENAME) { - Console.WriteLine("Loading template feature set..."); + Logger.WriteLine(Logger.Level.info, "Loading template feature set..."); m_TFeaturizer = new TemplateFeaturizer(strValue); continue; } else if (strKey == WORDEMBEDDING_COLUMN) { m_WordEmbeddingCloumn = int.Parse(strValue); - Console.WriteLine("Word embedding feature column: {0}", m_WordEmbeddingCloumn); + Logger.WriteLine(Logger.Level.info, "Word embedding feature column: {0}", m_WordEmbeddingCloumn); continue; } else if (strKey == TFEATURE_WEIGHT_TYPE) { - Console.WriteLine("TFeature weighting type: {0}", strValue); + Logger.WriteLine(Logger.Level.info, "TFeature weighting type: {0}", strValue); if (strValue == "binary") { m_TFeatureWeightType = TFEATURE_WEIGHT_TYPE_ENUM.BINARY; @@ -166,16 +167,16 @@ public void ShowFeatureSize() var fc = m_FeatureConfiguration; if (m_TFeaturizer != null) - Console.WriteLine("Template feature size: {0}", m_TFeaturizer.GetFeatureSize()); + Logger.WriteLine(Logger.Level.info, "Template feature size: {0}", m_TFeaturizer.GetFeatureSize()); if (fc.ContainsKey(TFEATURE_CONTEXT) == true) - Console.WriteLine("Template feature context size: {0}", m_TFeaturizer.GetFeatureSize() * fc[TFEATURE_CONTEXT].Count); + Logger.WriteLine(Logger.Level.info, "Template feature context size: {0}", m_TFeaturizer.GetFeatureSize() * fc[TFEATURE_CONTEXT].Count); if (fc.ContainsKey(RT_FEATURE_CONTEXT) == true) - Console.WriteLine("Run time feature size: {0}", m_TagSet.GetSize() * fc[RT_FEATURE_CONTEXT].Count); + Logger.WriteLine(Logger.Level.info, "Run time feature size: {0}", m_TagSet.GetSize() * fc[RT_FEATURE_CONTEXT].Count); if (fc.ContainsKey(WORDEMBEDDING_CONTEXT) == true) - Console.WriteLine("Word embedding feature size: {0}", m_WordEmbedding.GetDimension() * fc[WORDEMBEDDING_CONTEXT].Count); + Logger.WriteLine(Logger.Level.info, "Word embedding feature size: {0}", m_WordEmbedding.GetDimension() * fc[WORDEMBEDDING_CONTEXT].Count); } void ExtractSparseFeature(int currentState, int numStates, List features, State pState) diff --git a/RNNSharp/LSTMRNN.cs b/RNNSharp/LSTMRNN.cs index 3e10631..a423221 100644 --- a/RNNSharp/LSTMRNN.cs +++ b/RNNSharp/LSTMRNN.cs @@ -4,6 +4,7 @@ using System.Text; using System.Threading.Tasks; using System.IO; +using AdvUtils; namespace RNNSharp { @@ -135,7 +136,7 @@ private void saveLSTMWeight(LSTMWeight[][] weight, BinaryWriter fo) public override void loadNetBin(string filename) { - Console.WriteLine("Loading LSTM-RNN model: {0}", filename); + Logger.WriteLine(Logger.Level.info, "Loading LSTM-RNN model: {0}", filename); StreamReader sr = new StreamReader(filename); BinaryReader br = new BinaryReader(sr.BaseStream); @@ -367,7 +368,7 @@ public override void initMem() } } - Console.WriteLine("[TRACE] Initializing weights, random value is {0}", rand.NextDouble());// yy debug + Logger.WriteLine(Logger.Level.info, "[TRACE] Initializing weights, random value is {0}", rand.NextDouble());// yy debug initWeights(); } diff --git a/RNNSharp/ModelSetting.cs b/RNNSharp/ModelSetting.cs index 906f0ad..fe897c6 100644 --- a/RNNSharp/ModelSetting.cs +++ b/RNNSharp/ModelSetting.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using AdvUtils; namespace RNNSharp { @@ -66,34 +67,34 @@ public long GetSaveStep() public void DumpSetting() { - Console.WriteLine("Model File: {0}", m_strModelFile); + Logger.WriteLine(Logger.Level.info, "Model File: {0}", m_strModelFile); if (m_ModelType == 0) { - Console.WriteLine("Model Structure: Simple RNN"); - Console.WriteLine("BPTT: {0}", m_Bptt); + Logger.WriteLine(Logger.Level.info, "Model Structure: Simple RNN"); + Logger.WriteLine(Logger.Level.info, "BPTT: {0}", m_Bptt); } else if (m_ModelType == 1) { - Console.WriteLine("Model Structure: LSTM-RNN"); + Logger.WriteLine(Logger.Level.info, "Model Structure: LSTM-RNN"); } if (m_iDir == 0) { - Console.WriteLine("RNN Direction: Forward"); + Logger.WriteLine(Logger.Level.info, "RNN Direction: Forward"); } else { - Console.WriteLine("RNN Direction: Bi-directional"); + Logger.WriteLine(Logger.Level.info, "RNN Direction: Bi-directional"); } - Console.WriteLine("Learning rate: {0}", m_LearningRate); - Console.WriteLine("Dropout: {0}", m_Dropout); - Console.WriteLine("Max Iteration: {0}", m_MaxIteration); - Console.WriteLine("Hidden layer size: {0}", m_NumHidden); - Console.WriteLine("RNN-CRF: {0}", m_bCRFTraining); + Logger.WriteLine(Logger.Level.info, "Learning rate: {0}", m_LearningRate); + Logger.WriteLine(Logger.Level.info, "Dropout: {0}", m_Dropout); + Logger.WriteLine(Logger.Level.info, "Max Iteration: {0}", m_MaxIteration); + Logger.WriteLine(Logger.Level.info, "Hidden layer size: {0}", m_NumHidden); + Logger.WriteLine(Logger.Level.info, "RNN-CRF: {0}", m_bCRFTraining); if (m_SaveStep > 0) { - Console.WriteLine("Save temporary model after every {0} sentences", m_SaveStep); + Logger.WriteLine(Logger.Level.info, "Save temporary model after every {0} sentences", m_SaveStep); } } diff --git a/RNNSharp/RNN.cs b/RNNSharp/RNN.cs index 8bb7074..78013b8 100644 --- a/RNNSharp/RNN.cs +++ b/RNNSharp/RNN.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using System.Threading; using System.IO; +using AdvUtils; namespace RNNSharp { @@ -483,7 +484,7 @@ public virtual double TrainNet(DataSet trainingSet, int iter) { DateTime start = DateTime.Now; int[] predicted; - Console.WriteLine("[TRACE] Iter " + iter + " begins with learning rate alpha = " + alpha + " ..."); + Logger.WriteLine(Logger.Level.info, "[TRACE] Iter " + iter + " begins with learning rate alpha = " + alpha + " ..."); //Initialize varibles counter = 0; @@ -498,7 +499,7 @@ public virtual double TrainNet(DataSet trainingSet, int iter) int numSequence = trainingSet.GetSize(); int tknErrCnt = 0; int sentErrCnt = 0; - Console.WriteLine("[TRACE] Progress = 0/" + numSequence / 1000.0 + "K\r"); + Logger.WriteLine(Logger.Level.info, "[TRACE] Progress = 0/" + numSequence / 1000.0 + "K\r"); for (int curSequence = 0; curSequence < numSequence; curSequence++) { Sequence pSequence = trainingSet.Get(curSequence); @@ -532,18 +533,17 @@ public virtual double TrainNet(DataSet trainingSet, int iter) if ((curSequence + 1) % 1000 == 0) { - Console.WriteLine("[TRACE] Progress = {0} ", (curSequence + 1) / 1000 + "K/" + numSequence / 1000.0 + "K"); - Console.WriteLine(" train cross-entropy = {0} ", -logp / Math.Log10(2.0) / counter); - Console.WriteLine(" Error token ratio = {0}%", (double)tknErrCnt / (double)counter * 100); - Console.WriteLine(" Error sentence ratio = {0}%", (double)sentErrCnt / (double)curSequence * 100); + Logger.WriteLine(Logger.Level.info, "[TRACE] Progress = {0} ", (curSequence + 1) / 1000 + "K/" + numSequence / 1000.0 + "K"); + Logger.WriteLine(Logger.Level.info, " train cross-entropy = {0} ", -logp / Math.Log10(2.0) / counter); + Logger.WriteLine(Logger.Level.info, " Error token ratio = {0}%", (double)tknErrCnt / (double)counter * 100); + Logger.WriteLine(Logger.Level.info, " Error sentence ratio = {0}%", (double)sentErrCnt / (double)curSequence * 100); } if (m_SaveStep > 0 && (curSequence + 1) % m_SaveStep == 0) { //After processed every m_SaveStep sentences, save current model into a temporary file - Console.Write("Saving temporary model into file..."); + Logger.WriteLine(Logger.Level.info, "Saving temporary model into file..."); saveNetBin(m_strModelFile + ".tmp"); - Console.WriteLine("Done."); } } @@ -552,9 +552,9 @@ public virtual double TrainNet(DataSet trainingSet, int iter) double entropy = -logp / Math.Log10(2.0) / counter; double ppl = exp_10(-logp / counter); - Console.WriteLine("[TRACE] Iter " + iter + " completed"); - Console.WriteLine("[TRACE] Sentences = " + numSequence + ", time escape = " + duration + "s, speed = " + numSequence / duration.TotalSeconds); - Console.WriteLine("[TRACE] In training: log probability = " + logp + ", cross-entropy = " + entropy + ", perplexity = " + ppl); + Logger.WriteLine(Logger.Level.info, "[TRACE] Iter " + iter + " completed"); + Logger.WriteLine(Logger.Level.info, "[TRACE] Sentences = " + numSequence + ", time escape = " + duration + "s, speed = " + numSequence / duration.TotalSeconds); + Logger.WriteLine(Logger.Level.info, "[TRACE] In training: log probability = " + logp + ", cross-entropy = " + entropy + ", perplexity = " + ppl); return ppl; } @@ -831,7 +831,7 @@ public void CalculateOutputLayerError(State state, int timeat) public virtual bool ValidateNet(DataSet validationSet) { - Console.WriteLine("[TRACE] Start validation ..."); + Logger.WriteLine(Logger.Level.info, "[TRACE] Start validation ..."); int wordcn = 0; int[] predicted; int tknErrCnt = 0; @@ -875,17 +875,19 @@ public virtual bool ValidateNet(DataSet validationSet) double entropy = -logp / Math.Log10(2.0) / counter; double ppl = exp_10(-logp / counter); + double tknErrRatio = (double)tknErrCnt / (double)wordcn * 100; + double sentErrRatio = (double)sentErrCnt / (double)numSequence * 100; - Console.WriteLine("[TRACE] In validation: error token ratio = {0}% error sentence ratio = {1}%", (double)tknErrCnt / (double)wordcn * 100, (double)sentErrCnt / (double)numSequence * 100); - Console.WriteLine("[TRACE] In training: log probability = " + logp + ", cross-entropy = " + entropy + ", perplexity = " + ppl); - Console.WriteLine(); + Logger.WriteLine(Logger.Level.info, "[TRACE] In validation: error token ratio = {0}% error sentence ratio = {1}%", tknErrRatio, sentErrRatio); + Logger.WriteLine(Logger.Level.info, "[TRACE] In training: log probability = " + logp + ", cross-entropy = " + entropy + ", perplexity = " + ppl); + Logger.WriteLine(Logger.Level.info, ""); bool bUpdate = false; - if (ppl < minTknErrRatio) + if (tknErrRatio < minTknErrRatio) { //We have better result on validated set, save this model bUpdate = true; - minTknErrRatio = ppl; + minTknErrRatio = tknErrRatio; } return bUpdate; diff --git a/RNNSharp/RNNDecoder.cs b/RNNSharp/RNNDecoder.cs index ac8cde8..96ae4a7 100644 --- a/RNNSharp/RNNDecoder.cs +++ b/RNNSharp/RNNDecoder.cs @@ -4,6 +4,7 @@ using System.Text; using System.Threading.Tasks; using System.IO; +using AdvUtils; namespace RNNSharp { @@ -21,7 +22,7 @@ public RNNDecoder(string strModelFileName, Featurizer featurizer) if (modelDir == MODELDIRECTION.BI_DIRECTIONAL) { - Console.WriteLine("Model Structure: Bi-directional RNN"); + Logger.WriteLine(Logger.Level.info, "Model Structure: Bi-directional RNN"); if (modelType == MODELTYPE.SIMPLE) { m_Rnn = new BiRNN(new SimpleRNN(), new SimpleRNN()); @@ -35,18 +36,18 @@ public RNNDecoder(string strModelFileName, Featurizer featurizer) { if (modelType == MODELTYPE.SIMPLE) { - Console.WriteLine("Model Structure: Simple RNN"); + Logger.WriteLine(Logger.Level.info, "Model Structure: Simple RNN"); m_Rnn = new SimpleRNN(); } else { - Console.WriteLine("Model Structure: LSTM-RNN"); + Logger.WriteLine(Logger.Level.info, "Model Structure: LSTM-RNN"); m_Rnn = new LSTMRNN(); } } m_Rnn.loadNetBin(strModelFileName); - Console.WriteLine("CRF Model: {0}", m_Rnn.IsCRFModel()); + Logger.WriteLine(Logger.Level.info, "CRF Model: {0}", m_Rnn.IsCRFModel()); m_Featurizer = featurizer; } diff --git a/RNNSharp/RNNEncoder.cs b/RNNSharp/RNNEncoder.cs index 9dad154..cfd6111 100644 --- a/RNNSharp/RNNEncoder.cs +++ b/RNNSharp/RNNEncoder.cs @@ -4,6 +4,7 @@ using System.Text; using System.Threading.Tasks; using System.IO; +using AdvUtils; namespace RNNSharp { @@ -101,9 +102,9 @@ public void Train() rnn.setTagBigramTransition(m_LabelBigramTransition); } - Console.WriteLine(); + Logger.WriteLine(Logger.Level.info, ""); - Console.WriteLine("[TRACE] Iterative training begins ..."); + Logger.WriteLine(Logger.Level.info, "[TRACE] Iterative training begins ..."); double lastPPL = double.MaxValue; double lastAlpha = rnn.Alpha; int iter = 0; @@ -111,7 +112,7 @@ public void Train() { if (rnn.MaxIter > 0 && iter > rnn.MaxIter) { - Console.WriteLine("We have trained this model {0} iteration, exit."); + Logger.WriteLine(Logger.Level.info, "We have trained this model {0} iteration, exit."); break; } @@ -119,34 +120,32 @@ public void Train() double ppl = rnn.TrainNet(m_TrainingSet, iter); //Validate the model by validated corpus + bool betterValidateNet = false; if (rnn.ValidateNet(m_ValidationSet) == true) { //If current model is better than before, save it into file - Console.Write("Saving better model into file {0}...", m_modelSetting.GetModelFile()); + Logger.WriteLine(Logger.Level.info, "Saving better model into file {0}...", m_modelSetting.GetModelFile()); rnn.saveNetBin(m_modelSetting.GetModelFile()); - Console.WriteLine("Done."); - } - //else - //{ - // Console.Write("Loading previous best model from file {0}...", m_modelSetting.GetModelFile()); - // rnn.loadNetBin(m_modelSetting.GetModelFile()); - // Console.WriteLine("Done."); - // lastAlpha = rnn.Alpha; - // rnn.Alpha = rnn.Alpha / 2.0; - //} + betterValidateNet = true; + } + else + { + Logger.WriteLine(Logger.Level.info, "Loading previous best model from file {0}...", m_modelSetting.GetModelFile()); + rnn.loadNetBin(m_modelSetting.GetModelFile()); + } if (ppl >= lastPPL && lastAlpha != rnn.Alpha) { //Although we reduce alpha value, we still cannot get better result. - Console.WriteLine("Current perplexity({0}) is larger than the previous one({1}). End training early.", ppl, lastPPL); - Console.WriteLine("Current alpha: {0}, the previous alpha: {1}", rnn.Alpha, lastAlpha); + Logger.WriteLine(Logger.Level.info, "Current perplexity({0}) is larger than the previous one({1}). End training early.", ppl, lastPPL); + Logger.WriteLine(Logger.Level.info, "Current alpha: {0}, the previous alpha: {1}", rnn.Alpha, lastAlpha); break; } lastAlpha = rnn.Alpha; - if (ppl >= lastPPL) + if (betterValidateNet == false) { rnn.Alpha = rnn.Alpha / 2.0; } diff --git a/RNNSharp/Sentence.cs b/RNNSharp/Sentence.cs index 3f6a62d..103361d 100644 --- a/RNNSharp/Sentence.cs +++ b/RNNSharp/Sentence.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using AdvUtils; namespace RNNSharp { @@ -31,7 +32,7 @@ public void DumpFeatures() sb.Append('\t'); } - Console.WriteLine(sb.ToString().Trim()); + Logger.WriteLine(Logger.Level.info, sb.ToString().Trim()); } } diff --git a/RNNSharp/Sequence.cs b/RNNSharp/Sequence.cs index 590e3a6..f80e2ce 100644 --- a/RNNSharp/Sequence.cs +++ b/RNNSharp/Sequence.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using AdvUtils; namespace RNNSharp { @@ -41,7 +42,7 @@ public bool SetLabel(Sentence sent, TagSet tagSet) int tagId = tagSet.GetIndex(strTagName); if (tagId < 0) { - Console.WriteLine("Error: tag {0} is unknown.", strTagName); + Logger.WriteLine(Logger.Level.info, "Error: tag {0} is unknown.", strTagName); return false; } diff --git a/RNNSharp/SimpleRNN.cs b/RNNSharp/SimpleRNN.cs index a4ef162..81257af 100644 --- a/RNNSharp/SimpleRNN.cs +++ b/RNNSharp/SimpleRNN.cs @@ -4,6 +4,7 @@ using System.Text; using System.Threading.Tasks; using System.IO; +using AdvUtils; namespace RNNSharp { @@ -325,7 +326,7 @@ public override void initMem() mat_hiddenBpttWeight = new Matrix(L1, L1); - Console.WriteLine("[TRACE] Initializing weights, random value is {0}", rand.NextDouble());// yy debug + Logger.WriteLine(Logger.Level.info, "[TRACE] Initializing weights, random value is {0}", rand.NextDouble());// yy debug initWeights(); //Initialize BPTT @@ -398,7 +399,7 @@ public override void netFlush() //cleans all activations and error vectors public override void loadNetBin(string filename) { - Console.WriteLine("Loading SimpleRNN model: {0}", filename); + Logger.WriteLine(Logger.Level.info, "Loading SimpleRNN model: {0}", filename); StreamReader sr = new StreamReader(filename); BinaryReader br = new BinaryReader(sr.BaseStream); diff --git a/RNNSharp/TemplateFeaturizer.cs b/RNNSharp/TemplateFeaturizer.cs index a7e9f0c..4dfa81e 100644 --- a/RNNSharp/TemplateFeaturizer.cs +++ b/RNNSharp/TemplateFeaturizer.cs @@ -162,7 +162,7 @@ public void BuildIndexedFeatureIntoFile(string strFileName, List feature { if (strFeature.StartsWith("U") == false) { - Console.WriteLine("Invalidated feature: {0}", strFeature); + Logger.WriteLine(Logger.Level.info, "Invalidated feature: {0}", strFeature); continue; } diff --git a/RNNSharpConsole/Program.cs b/RNNSharpConsole/Program.cs index 62d41b4..36cbd48 100644 --- a/RNNSharpConsole/Program.cs +++ b/RNNSharpConsole/Program.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using System.IO; using RNNSharp; +using AdvUtils; namespace RNNSharpConsole { @@ -37,57 +38,57 @@ static void Usage() { UsageTitle(); Console.WriteLine("RNNSharpConsole.exe "); - Console.WriteLine(" -mode : support train/test"); + Console.WriteLine(" -mode : train/test"); } static void UsageTrain() { UsageTitle(); Console.WriteLine("RNNSharpConsole.exe -mode train "); - Console.WriteLine("Parameters for training RNN"); + Console.WriteLine("Parameters for RNN training"); Console.WriteLine(" -trainfile "); Console.WriteLine("\tTraining corpus file"); - + Console.WriteLine(" -validfile "); Console.WriteLine("\tValidated corpus file for training"); - + Console.WriteLine(" -modelfile "); Console.WriteLine("\tEncoded model file"); - + Console.WriteLine(" -modeltype "); - Console.WriteLine("\tModel structure: 0 - simple RNN, 1 - LSTM-RNN, default is 0"); + Console.WriteLine("\tModel type: 0 - BPTT-RNN, 1 - LSTM-RNN, default is 0"); Console.WriteLine(" -dir "); - Console.WriteLine("\tRNN directional: 0 - Forward RNN, 1 - Bi-directional RNN, default is 0"); - + Console.WriteLine("\tRecurrent direction: 0 - Forward RNN, 1 - Bi-directional RNN, default is 0"); + Console.WriteLine(" -ftrfile "); Console.WriteLine("\tFeature configuration file"); - + Console.WriteLine(" -tagfile "); Console.WriteLine("\tSupported output tagid-name list file"); - + Console.WriteLine(" -alpha "); - Console.WriteLine("\tLearning rate, default is 0.1"); - + Console.WriteLine("\tInitializing learning rate, default is 0.1"); + Console.WriteLine(" -dropout "); - Console.WriteLine("\tDropout parameter [0, 1.0), default is 0"); - + Console.WriteLine("\tDropout ratio [0, 1.0), default is 0"); + Console.WriteLine(" -layersize "); - Console.WriteLine("\tHidden layer size for training, default is 200"); - + Console.WriteLine("\tHidden layer size, default is 200"); + Console.WriteLine(" -bptt "); - Console.WriteLine("\tStep for back-propagation through time for simple RNN. default is 4"); - - Console.WriteLine(" -crf <0/1>"); - Console.WriteLine("\tTraining model by RNN(0) or RNN-CRF(1), default is 0"); - + Console.WriteLine("\tStep for back-propagation through time for BPTT-RNN. default is 4"); + + Console.WriteLine(" -crf "); + Console.WriteLine("\tEnable CRF model at output, 0 is disable, 1 is enable. default is 0"); + Console.WriteLine(" -maxiter "); - Console.WriteLine("\tMaximum iteration for training, default is 20"); - + Console.WriteLine("\tMaximum iteration for training, 0 is unlimited. default is 20"); + Console.WriteLine(" -savestep "); - Console.WriteLine("\tSave temporary model after every sentence, default is 0"); - + Console.WriteLine("\tSave temporary model after every sentences, default is 0"); + Console.WriteLine(); Console.WriteLine("Example: RNNSharpConsole.exe -mode train -trainfile train.txt -validfile valid.txt -modelfile model.bin -ftrfile features.txt -tagfile tags.txt -modeltype 0 -layersize 200 -alpha 0.1 -crf 1 -maxiter 20 -savestep 200K -dir 0"); @@ -97,25 +98,25 @@ static void UsageTest() { UsageTitle(); Console.WriteLine("RNNSharpConsole.exe -mode test "); - Console.WriteLine("Parameters for predicting tags from given corpus"); + Console.WriteLine("Parameters to predict tags from given corpus by using trained model"); Console.WriteLine(" -testfile "); Console.WriteLine("\tTraining corpus file"); - + Console.WriteLine(" -modelfile "); Console.WriteLine("\tEncoded model file"); - + Console.WriteLine(" -tagfile "); Console.WriteLine("\tSupported output tagid-name list file"); - + Console.WriteLine(" -ftrfile "); Console.WriteLine("\tFeature configuration file"); - + Console.WriteLine(" -outfile "); Console.WriteLine("\tResult output file"); Console.WriteLine(" -nbest "); Console.WriteLine("\tGet N-best result. Default is 1"); - + Console.WriteLine(); Console.WriteLine("Example: RNNSharpConsole.exe -mode test -testfile test.txt -modelfile model.bin -tagfile tags.txt -ftrfile features.txt -outfile result.txt -nbest 3"); } @@ -174,7 +175,7 @@ static int ArgPos(string str, string[] args) { if (a == args.Length - 1) { - Console.WriteLine("Argument missing for {0}", str); + Logger.WriteLine(Logger.Level.info, "Argument missing for {0}", str); return -1; } return a; @@ -206,7 +207,7 @@ static void CheckCorpus(string strFileName) } } - Console.WriteLine("Record set size in {0}: {1}", strFileName, RecordCount); + Logger.WriteLine(Logger.Level.info, "Record set size in {0}: {1}", strFileName, RecordCount); sr.Close(); } @@ -235,7 +236,7 @@ static void LoadDataset(string strFileName, Featurizer featurizer, DataSet dataS //Set label for the sequence if (seq.SetLabel(sent, featurizer.GetTagSet()) == false) { - Console.WriteLine("Error: Invalidated record."); + Logger.WriteLine(Logger.Level.info, "Error: Invalidated record."); sent.DumpFeatures(); continue; } @@ -247,12 +248,10 @@ static void LoadDataset(string strFileName, Featurizer featurizer, DataSet dataS RecordCount++; if (RecordCount % 10000 == 0) { - Console.Write("{0}...", RecordCount); + Logger.WriteLine(Logger.Level.info, "{0}...", RecordCount); } } - Console.WriteLine(); - sr.Close(); } @@ -280,7 +279,7 @@ static void Main(string[] args) } else { - Console.WriteLine("Specify running mode is required."); + Logger.WriteLine(Logger.Level.err, "Running mode is required."); Usage(); } } @@ -310,7 +309,7 @@ private static void Test() { if (String.IsNullOrEmpty(strTagFile) == true) { - Console.WriteLine("FAILED: The tag mapping file {0} isn't specified.", strTagFile); + Logger.WriteLine(Logger.Level.err, "FAILED: The tag mapping file {0} isn't specified.", strTagFile); UsageTest(); return; } @@ -320,21 +319,21 @@ private static void Test() if (String.IsNullOrEmpty(strModelFile) == true) { - Console.WriteLine("FAILED: The model file {0} isn't specified.", strModelFile); + Logger.WriteLine(Logger.Level.err, "FAILED: The model file {0} isn't specified.", strModelFile); UsageTest(); return; } if (String.IsNullOrEmpty(strFeatureConfigFile) == true) { - Console.WriteLine("FAILED: The feature configuration file {0} isn't specified.", strFeatureConfigFile); + Logger.WriteLine(Logger.Level.err, "FAILED: The feature configuration file {0} isn't specified.", strFeatureConfigFile); UsageTest(); return; } if (strOutputFile.Length == 0) { - Console.WriteLine("FAILED: The output file name should not be empty."); + Logger.WriteLine(Logger.Level.err, "FAILED: The output file name should not be empty."); UsageTest(); return; } @@ -351,7 +350,7 @@ private static void Test() if (File.Exists(strTestFile) == false) { - Console.WriteLine("FAILED: The test corpus {0} isn't existed.", strTestFile); + Logger.WriteLine(Logger.Level.err, "FAILED: The test corpus {0} isn't existed.", strTestFile); UsageTest(); return; } @@ -392,7 +391,7 @@ private static void Test() int[][] output = decoder.ProcessNBest(sent, nBest); if (output == null) { - Console.WriteLine("FAILED: decode failed. Dump current sentence..."); + Logger.WriteLine(Logger.Level.err, "FAILED: decode failed. Dump current sentence..."); sent.DumpFeatures(); return; } @@ -420,9 +419,11 @@ private static void Test() private static void Train() { + Logger.LogFile = "RNNSharpConsole.log"; + if (File.Exists(strTagFile) == false) { - Console.WriteLine("FAILED: The tag mapping file {0} isn't existed.", strTagFile); + Logger.WriteLine(Logger.Level.err, "FAILED: The tag mapping file {0} isn't existed.", strTagFile); UsageTrain(); return; } @@ -448,7 +449,7 @@ private static void Train() if (File.Exists(strFeatureConfigFile) == false) { - Console.WriteLine("FAILED: The feature configuration file {0} isn't existed.", strFeatureConfigFile); + Logger.WriteLine(Logger.Level.err, "FAILED: The feature configuration file {0} isn't existed.", strFeatureConfigFile); UsageTrain(); return; } @@ -458,13 +459,13 @@ private static void Train() if (featurizer.IsRunTimeFeatureUsed() == true && iDir == 1) { - Console.WriteLine("FAILED: Run time feature is not available for bi-directional RNN model."); + Logger.WriteLine(Logger.Level.err, "FAILED: Run time feature is not available for bi-directional RNN model."); UsageTrain(); return; } if (String.IsNullOrEmpty(strTrainFile) == true) { - Console.WriteLine("FAILED: The training corpus isn't specified."); + Logger.WriteLine(Logger.Level.err, "FAILED: The training corpus isn't specified."); UsageTrain(); return; } @@ -476,7 +477,7 @@ private static void Train() DataSet dataSetValidation = null; if (String.IsNullOrEmpty(strValidFile) == true) { - Console.WriteLine("FAILED: The validation corpus isn't specified."); + Logger.WriteLine(Logger.Level.err, "FAILED: The validation corpus isn't specified."); return; } //LoadFeatureConfig validated corpus and extract feature set @@ -490,7 +491,7 @@ private static void Train() if (iCRF == 1) { - Console.WriteLine("Initialize output tag bigram transition probability..."); + Logger.WriteLine(Logger.Level.info, "Initialize output tag bigram transition probability..."); //Build tag bigram transition matrix dataSetTrain.BuildLabelBigramTransition(); encoder.SetLabelBigramTransition(dataSetTrain.GetLabelBigramTransition()); diff --git a/RNNSharpConsole/RNNSharpConsole.csproj b/RNNSharpConsole/RNNSharpConsole.csproj index 3e23a86..b939270 100644 --- a/RNNSharpConsole/RNNSharpConsole.csproj +++ b/RNNSharpConsole/RNNSharpConsole.csproj @@ -32,6 +32,10 @@ 4 + + False + ..\dll\AdvUtils.dll + diff --git a/TFeatureBin/Program.cs b/TFeatureBin/Program.cs index b42d828..1e8e625 100644 --- a/TFeatureBin/Program.cs +++ b/TFeatureBin/Program.cs @@ -27,7 +27,7 @@ static int ArgPos(string str, string[] args) { if (a == args.Length - 1) { - Console.WriteLine("Argument missing for {0}", str); + Logger.WriteLine(Logger.Level.info, "Argument missing for {0}", str); return -1; } return a; @@ -161,11 +161,11 @@ static void BuildMode() static IDictionary ExtractFeatureSetFromFile() { //Load templates from given file - Console.WriteLine("Loading feature template from {0}...", strTemplateFile); + Logger.WriteLine(Logger.Level.info, "Loading feature template from {0}...", strTemplateFile); templateFeaturizer = new TemplateFeaturizer(); templateFeaturizer.LoadTemplateFromFile(strTemplateFile); - Console.WriteLine("Generate feature set..."); + Logger.WriteLine(Logger.Level.info, "Generate feature set..."); BigDictionary feature2freq = new BigDictionary(); List record = new List(); StreamReader srCorpus = new StreamReader(strInputFile, Encoding.UTF8); @@ -218,7 +218,7 @@ static IDictionary ExtractFeatureSetFromFile() srCorpus.Close(); //Only save the feature whose frequency is not less than minfreq - Console.WriteLine("Filter out features whose frequency is less than {0}", minfreq); + Logger.WriteLine(Logger.Level.info, "Filter out features whose frequency is less than {0}", minfreq); SortedDictionary features = new SortedDictionary(StringComparer.Ordinal); foreach (KeyValuePair pair in feature2freq) { diff --git a/dll/AdvUtils.dll b/dll/AdvUtils.dll index 4627081a0d60d5d71cbbaf3f94ef2d552e859665..337a33aa5e23c5a7930bcf69d429f09630ab7034 100644 GIT binary patch literal 62464 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 naF0hT!Pho8(qy}!@zAD#2ubM86k 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