This commit is contained in:
Andre Martins 2016-09-14 08:39:31 +01:00
commit e50604b857
11 changed files with 275 additions and 7 deletions

1
.gitignore vendored
View File

@ -39,3 +39,4 @@ build
# Examples
examples/*/*.gz
examples/mnist/*ubyte

View File

@ -2,10 +2,13 @@
all: download
download: train-images-idx3-ubyte.gz train-labels-idx1-ubyte.gz t10k-images-idx3-ubyte.gz t10k-labels-idx3-ubyte.gz
download: train-images-idx3-ubyte train-labels-idx1-ubyte t10k-images-idx3-ubyte t10k-labels-idx1-ubyte
%.gz:
wget http://yann.lecun.com/exdb/mnist/$*.gz -O $@
%-ubyte: %-ubyte.gz
gzip -d < $^ > $@
%-ubyte.gz:
wget http://yann.lecun.com/exdb/mnist/$*-ubyte.gz -O $@
clean:
rm -f *.gz
rm -f *.gz *-ubyte

4
examples/xor/label.txt Normal file
View File

@ -0,0 +1,4 @@
1
1
0
0

4
examples/xor/train.txt Normal file
View File

@ -0,0 +1,4 @@
0 0
1 1
1 0
0 1

View File

@ -56,11 +56,11 @@
</tool>
</toolChain>
</folderInfo>
<fileInfo id="com.nvidia.cuda.ide.seven_five.configuration.debug.1479727693.1233477758" name="tensor.cu" rcbsApplicability="disable" resourcePath="tensor.cu" toolsToInvoke="nvcc.compiler.base.1979453423.1456105605">
<tool id="nvcc.compiler.base.1979453423.1456105605" name="NVCC Compiler" superClass="nvcc.compiler.base.1979453423"/>
<fileInfo id="com.nvidia.cuda.ide.seven_five.configuration.debug.1479727693.1770712140" name="tensor.cu" rcbsApplicability="disable" resourcePath="tensor.cu" toolsToInvoke="nvcc.compiler.base.1979453423.1452902875">
<tool id="nvcc.compiler.base.1979453423.1452902875" name="NVCC Compiler" superClass="nvcc.compiler.base.1979453423"/>
</fileInfo>
<sourceEntries>
<entry excluding="tensor.cu" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>

View File

@ -85,6 +85,11 @@
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/src/marian.h</locationURI>
</link>
<link>
<name>mnist.h</name>
<type>1</type>
<locationURI>PARENT-1-PROJECT_LOC/src/mnist.h</locationURI>
</link>
<link>
<name>tensor.cu</name>
<type>1</type>

View File

@ -10,6 +10,7 @@ cuda_add_executable(
test.cu
expressions.cu
tensor_operators.cu
tensor.cu
$<TARGET_OBJECTS:libcommon>
)

107
src/mnist.h Normal file
View File

@ -0,0 +1,107 @@
//#pragma once
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <cassert>
namespace datasets {
namespace mnist {
typedef unsigned char uchar;
const size_t IMAGE_SIZE = 784;
const size_t LABEL_SIZE = 10;
const size_t IMAGE_MAGIC_NUMBER = 2051;
const size_t LABEL_MAGIC_NUMBER = 2049;
auto reverseInt = [](int i) {
unsigned char c1, c2, c3, c4;
c1 = i & 255, c2 = (i >> 8) & 255, c3 = (i >> 16) & 255, c4 = (i >> 24) & 255;
return ((int)c1 << 24) + ((int)c2 << 16) + ((int)c3 << 8) + c4;
};
std::vector<float> ReadImages(const std::string& full_path, int& number_of_images) {
std::ifstream file(full_path);
if (! file.is_open())
throw std::runtime_error("Cannot open file `" + full_path + "`!");
int magic_number = 0;
file.read((char *)&magic_number, sizeof(magic_number));
magic_number = reverseInt(magic_number);
if (magic_number != IMAGE_MAGIC_NUMBER)
throw std::runtime_error("Invalid MNIST image file!");
int n_rows = 0;
int n_cols = 0;
file.read((char *)&number_of_images, sizeof(number_of_images)), number_of_images = reverseInt(number_of_images);
file.read((char *)&n_rows, sizeof(n_rows)), n_rows = reverseInt(n_rows);
file.read((char *)&n_cols, sizeof(n_cols)), n_cols = reverseInt(n_cols);
assert(n_rows * n_cols == IMAGE_SIZE);
int n = number_of_images * IMAGE_SIZE;
std::vector<float> _dataset(n);
for (int i = 0; i < n; i++) {
unsigned char pixel = 0;
file.read((char*)&pixel, sizeof(pixel));
_dataset[i] = pixel / 255.0f;
}
return _dataset;
}
std::vector<float> ReadLabels(const std::string& full_path, int& number_of_labels) {
std::ifstream file(full_path);
if (! file.is_open())
throw std::runtime_error("Cannot open file `" + full_path + "`!");
int magic_number = 0;
file.read((char *)&magic_number, sizeof(magic_number));
magic_number = reverseInt(magic_number);
if (magic_number != LABEL_MAGIC_NUMBER)
throw std::runtime_error("Invalid MNIST label file!");
file.read((char *)&number_of_labels, sizeof(number_of_labels)), number_of_labels = reverseInt(number_of_labels);
int n = number_of_labels * LABEL_SIZE;
std::vector<float> _dataset(n, 0.0f);
for (int i = 0; i < number_of_labels; i++) {
unsigned char label;
file.read((char*)&label, 1);
_dataset[(i * 10) + (int)(label)] = 1.0f;
}
return _dataset;
}
} // namespace mnist
} // namespace datasets
//int main(int argc, const char *argv[]) {
//int numImg = 0;
//auto images = datasets::mnist::ReadImages("../examples/mnist/t10k-images-idx3-ubyte", numImg);
//auto labels = datasets::mnist::ReadLabels("../examples/mnist/t10k-labels-idx1-ubyte", numImg);
//std::cout << "Number of images: " << numImg << std::endl;
//for (int i = 0; i < 3; i++) {
//for (int j = 0; j < datasets::mnist::IMAGE_SIZE; j++) {
//std::cout << images[(i * datasets::mnist::IMAGE_SIZE) + j] << ",";
//}
//std::cout << "\nlabels= ";
//for (int k = 0; k < 10; k++) {
//std::cout << labels[(i * 10) + k] << ",";
//}
//std::cout << std::endl;
//}
//return 0;
//}

93
src/tensor.cu Normal file
View File

@ -0,0 +1,93 @@
#include <fstream>
#include "tensor.h"
using namespace std;
namespace marian {
inline std::vector<std::string> Tokenize(const std::string& str,
const std::string& delimiters = " \t")
{
std::vector<std::string> tokens;
// Skip delimiters at beginning.
std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
// Find first "non-delimiter".
std::string::size_type pos = str.find_first_of(delimiters, lastPos);
while (std::string::npos != pos || std::string::npos != lastPos) {
// Found a token, add it to the vector.
tokens.push_back(str.substr(lastPos, pos - lastPos));
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
pos = str.find_first_of(delimiters, lastPos);
}
return tokens;
}
//! convert string to variable of type T. Used to reading floats, int etc from files
template<typename T>
T Scan(const std::string &input)
{
std::stringstream stream(input);
T ret;
stream >> ret;
return ret;
}
//! convert vectors of string to vectors of type T variables
template<typename T>
inline std::vector<T> Scan(const std::vector< std::string > &input)
{
std::vector<T> output(input.size());
for (size_t i = 0 ; i < input.size() ; i++) {
output[i] = Scan<T>( input[i] );
}
return output;
}
//! tokenise input string to vector of type T
template<typename T>
inline std::vector<T> Tokenize( const std::string &input
, const std::string& delimiters = " \t")
{
std::vector<std::string> stringVector = Tokenize(input, delimiters);
return Scan<T>( stringVector );
}
void Tensor::Load(const std::string &path)
{
size_t totSize = std::accumulate(pimpl_->shape().begin(), pimpl_->shape().end(),
1, std::multiplies<int>());
cerr << "totSize=" << totSize << endl;
std::vector<float> hostData(totSize);
fstream strm;
strm.open(path.c_str());
string line;
size_t ind = 0;
while ( getline (strm, line) )
{
cerr << line << '\n';
vector<Float> toks = Tokenize<Float>(line);
for (size_t i = 0; i < toks.size(); ++i) {
hostData[ind] = toks[i];
}
++ind;
}
strm.close();
Load(hostData);
}
void Tensor::Load(const std::vector<float> &values)
{
pimpl_->set(values);
}
}

View File

@ -152,6 +152,14 @@ class TensorImpl {
thrust::fill(data_.begin(), data_.end(), value);
}
void set(const std::vector<Float> &values) {
size_t totSize = std::accumulate(shape().begin(), shape().end(),
1, std::multiplies<int>());
std::cerr << "totSize=" << totSize << " " << values.size() << std::endl;
assert(totSize == values.size());
thrust::copy(values.begin(), values.end(), data_.begin());
}
std::string Debug() const
{
std::stringstream strm;
@ -247,6 +255,9 @@ class Tensor {
std::cerr << std::endl;
}
void Load(const std::string &path);
void Load(const std::vector<float> &values);
};
}

View File

@ -1,13 +1,18 @@
#include "marian.h"
#include "mnist.h"
using namespace std;
int main(int argc, char** argv) {
/*int numImg = 0;*/
/*auto images = datasets::mnist::ReadImages("../examples/mnist/t10k-images-idx3-ubyte", numImg);*/
/*auto labels = datasets::mnist::ReadLabels("../examples/mnist/t10k-labels-idx1-ubyte", numImg);*/
using namespace marian;
using namespace keywords;
Expr x = input(shape={whatevs, 784}, name="X");
Expr y = input(shape={whatevs, 10}, name="Y");
@ -22,8 +27,17 @@ int main(int argc, char** argv) {
Tensor tx({500, 784}, 1);
Tensor ty({500, 10}, 1);
#if 0
int numImg, imgSize;
vector<float> images = datasets::mnist::ReadImages("../examples/mnist/t10k-images-idx3-ubyte", numImg, imgSize);
vector<int> labels = datasets::mnist::ReadLabels("../examples/mnist/t10k-labels-idx1-ubyte");
tx.Load(images);
//ty.Load(labels);
cerr << "tx=" << tx.Debug() << endl;
cerr << "ty=" << ty.Debug() << endl;
#endif
x = tx;
y = ty;
@ -52,6 +66,31 @@ int main(int argc, char** argv) {
//std::cerr << graph["pred"].val()[0] << std::endl;
// XOR
/*
Expr x = input(shape={whatevs, 2}, name="X");
Expr y = input(shape={whatevs, 2}, name="Y");
Expr w = param(shape={2, 1}, name="W0");
Expr b = param(shape={1, 1}, name="b0");
Expr n5 = dot(x, w);
Expr n6 = n5 + b;
Expr lr = softmax(n6, axis=1, name="pred");
cerr << "lr=" << lr.Debug() << endl;
Expr graph = -mean(sum(y * log(lr), axis=1), axis=0, name="cost");
Tensor tx({4, 2}, 1);
Tensor ty({4, 1}, 1);
cerr << "tx=" << tx.Debug() << endl;
cerr << "ty=" << ty.Debug() << endl;
tx.Load("../examples/xor/train.txt");
ty.Load("../examples/xor/label.txt");
*/
#if 0
hook0(graph);
graph.autodiff();