You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by gi...@git.apache.org on 2017/10/11 18:10:29 UTC

[GitHub] f-matt commented on issue #8126: Not able to train a neural network [XOR added]

f-matt commented on issue #8126: Not able to train a neural network [XOR added]
URL: https://github.com/apache/incubator-mxnet/issues/8126#issuecomment-335899162
 
 
   I'm just starting to study MXNet, but this example is working here (CPU only).
   
   ```c++
   #include "mxnet-cpp/MxNetCpp.h"
   
   #include <chrono>
   #include <iostream>
   
   using namespace std;
   using namespace mxnet::cpp;
   
   Symbol mlp(const vector<int> &layers) {
   	auto x = Symbol::Variable("X");
   	auto label = Symbol::Variable("label");
   
   	vector<Symbol> weights(layers.size());
   	vector<Symbol> biases(layers.size());
   	vector<Symbol> outputs(layers.size());
   
   	for (size_t i = 0; i < layers.size(); ++i) {
   		weights[i] = Symbol::Variable("w" + to_string(i));
   		biases[i] = Symbol::Variable("b" + to_string(i));
   		Symbol fc = FullyConnected(
   				i == 0 ? x : outputs[i-1],
   						weights[i],
   						biases[i],
   						layers[i]);
   
   		outputs[i] = i == layers.size() - 1 ? fc :
   				Activation(fc, ActivationActType::kRelu);
   	}
   
   	return SoftmaxOutput(outputs.back(), label);
   
   }
   
   
   int main(int argc, char *argv[]) {
   
   	const int input_width = 2;
   	const int input_height = 1;
   	const int output_length = 2;
   	const size_t train_num = 8000;
   	const size_t val_num = 2000;
   	const vector<int> layers{8, 8, 2};
   	const int batch_size = 64;
   	const int max_epoch = 10;
   	const float learning_rate = 0.01;
   	const float weight_decay = 1e-2;
   
   	vector<float> data;
   	vector<float> labels;
   
   	for (int i = 0; i < 10000; ++i) {
   
   		int x1 = rand() % 2;
   		int x2 = rand() % 2;
   
   		int y = x1 ^ x2;
   
   		data.push_back(x1);
   		data.push_back(x2);
   
   		labels.push_back(y == 0 ? 0 : 1);
   		labels.push_back(y == 0 ? 1 : 0);
   
   	}
   
   	const float *dptr = data.data();
   	const float *lptr = labels.data();
   
   	Context ctx = Context::cpu();
   
   	NDArray data_array = NDArray(Shape(10000, 1, input_width, input_height), ctx);
   	NDArray label_array = NDArray(Shape(10000, output_length), ctx);
   
   	data_array.SyncCopyFromCPU(dptr, 10000 * input_width * input_height);
   	label_array.SyncCopyFromCPU(lptr, 10000 * output_length);
   	data_array.WaitToRead();
   	label_array.WaitToRead();
   
   	NDArray train_data = data_array.Slice(0, 8000);
   	NDArray train_label = label_array.Slice(0, 8000);
   
   	NDArray val_data = data_array.Slice(8000, 10000);
   	NDArray val_label = label_array.Slice(8000, 10000);
   
   	auto net = mlp(layers);
   
   	std::map<string, NDArray> args;
   
   	args["X"] = NDArray(Shape(batch_size, 1, input_width, input_height), ctx);
   	args["label"] = NDArray(Shape(batch_size, output_length), ctx);
   
   	net.InferArgsMap(ctx, &args, args);
   
   	auto initializer = Uniform(0.001);
   	for (auto &arg : args) {
   		initializer(arg.first, &arg.second);
   	}
   
   	Optimizer* opt = OptimizerRegistry::Find("adam");
   	opt->SetParam("lr", learning_rate)
   			->SetParam("wd", weight_decay);
   
   	auto *exec = net.SimpleBind(ctx, args);
   	auto arg_names = net.ListArguments();
   
   	for (int iter = 0; iter < max_epoch; ++iter) {
   
   		int samples = 0;
   
   		auto tic = chrono::system_clock::now();
   
   		size_t start_index = 0;
   		size_t correct_count = 0;
   		size_t all_count = 0;
   
   		while (start_index < train_num) {
   
   			if (start_index + batch_size > train_num) {
   				start_index = train_num - batch_size;
   			}
   
   			train_data.Slice(start_index, start_index + batch_size).CopyTo(&args["X"]);
   			train_label.Slice(start_index, start_index + batch_size).CopyTo(&args["label"]);
   
   			NDArray::WaitAll();
   
   			exec->Forward(true);
   			exec->Backward();
   
   			for (size_t i = 0; i < arg_names.size(); ++i) {
   				if (arg_names[i] == "X"  || arg_names[i] == "label")
   					continue;
   
   				opt->Update(i, exec->arg_arrays[i], exec->grad_arrays[i]);
   			}
   
   			NDArray y(Shape(batch_size, output_length), ctx);
   			NDArray y_pred(Shape(batch_size, output_length), ctx);
   
   			train_label.Slice(start_index, start_index + batch_size).CopyTo(&y);
   			exec->outputs[0].CopyTo(&y_pred);
   
   			NDArray::WaitAll();
   
   			const mx_float *ptr_y = y.GetData();
   			const mx_float *ptr_y_pred = y_pred.GetData();
   
   			for(int i = 0; i < batch_size; ++i) {
   
   				all_count++;
   
   				int correct = ptr_y[2*i] < ptr_y[2*i+1] ? 0 : 1;
   				int predicted = ptr_y_pred[2*i] < ptr_y_pred[2*i+1] ? 0 : 1;
   
   				if (correct == predicted)
   					correct_count++;
   
   			}
   
   			start_index += batch_size;
   			samples += batch_size;
   
   		}
   
   		auto toc = chrono::system_clock::now();
   		float duration = chrono::duration_cast<chrono::milliseconds> (toc - tic).count() / 1000.0;
   		float train_acc = (float) correct_count / all_count;
   
   		correct_count = 0;
   		all_count = 0;
   
   		start_index = 0;
   
   		while (start_index < val_num) {
   
   			if (start_index + batch_size > val_num) {
   				start_index = val_num - batch_size;
   			}
   
   			val_data.Slice(start_index, start_index + batch_size).CopyTo(&args["X"]);
   			val_label.Slice(start_index, start_index + batch_size).CopyTo(&args["label"]);
   
   			start_index += batch_size;
   
   			NDArray::WaitAll();
   
   			exec->Forward(false);
   
   			const auto &out = exec->outputs;
   
   			NDArray label_cpu(Shape(batch_size, output_length), ctx);
   			NDArray out_cpu(Shape(batch_size, output_length), ctx);
   
   			out[0].CopyTo(&out_cpu);
   			val_label.Slice(start_index - batch_size, start_index).CopyTo(&label_cpu);
   
   			NDArray::WaitAll();
   
   			const mx_float *dptr_out = out_cpu.GetData();
   			const mx_float *dptr_label = label_cpu.GetData();
   
   			for(int i = 0; i < batch_size; ++i) {
   				all_count++;
   
   				int correct = dptr_label[2*i] < dptr_label[2*i+1] ? 0 : 1;
   				int predicted = dptr_out[2*i] < dptr_out[2*i+1] ? 0 : 1;
   
   				if (correct == predicted)
   					correct_count++;
   
   			}
   
   		}
   
   		LG << "Epoch: " << iter << " " << samples/duration << " samples/sec Train-Accuracy: " << train_acc << " Val-Accuracy: " << (float) correct_count / all_count;
   
   	}
   
   	delete exec;
   	MXNotifyShutdown();
   
   	return 0;
   
   }
   ```
 
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services