Initial size handling
This commit is contained in:
parent
e028ad1a41
commit
b2c393d23a
28 changed files with 543 additions and 135 deletions
|
|
@ -18,7 +18,7 @@ void loadImage(Buffer<halnf>& output, const char* name) {
|
|||
|
||||
output.reserve(x * y);
|
||||
|
||||
for (auto i : Range(output.size())) {
|
||||
for (auto i : IterRange(output.size())) {
|
||||
output[i] = loadedImage[i * 4] / 255.f;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ bool loadDataset(Dataset& out, const std::string& location) {
|
|||
out.labels.reserve(out.length);
|
||||
out.images.reserve(out.length);
|
||||
|
||||
for (auto i : Range(out.length)) {
|
||||
for (auto i : IterRange(out.length)) {
|
||||
auto& image = out.images[i];
|
||||
image.reserve(sizeX * sizeY);
|
||||
dataset.readBytes((LocalConnection::Byte*) image.getBuff(), sizeX * sizeY);
|
||||
|
|
@ -89,7 +89,7 @@ struct NumberRec {
|
|||
}
|
||||
|
||||
mTestcases.reserve(dataset.images.size());
|
||||
for (auto i : Range(dataset.images.size())) {
|
||||
for (auto i : IterRange(dataset.images.size())) {
|
||||
auto& image = dataset.images[i];
|
||||
auto label = dataset.labels[i];
|
||||
|
||||
|
|
@ -97,13 +97,13 @@ struct NumberRec {
|
|||
|
||||
testcase.output.reserve(10);
|
||||
|
||||
for (auto dig : Range(10)) {
|
||||
for (auto dig : IterRange(10)) {
|
||||
testcase.output[dig] = label == dig ? 1 : 0;
|
||||
}
|
||||
|
||||
testcase.input.reserve(image.size());
|
||||
|
||||
for (auto pxl : Range(image.size())) {
|
||||
for (auto pxl : IterRange(image.size())) {
|
||||
testcase.input[pxl] = (halnf) image[pxl] / 255.f;
|
||||
}
|
||||
}
|
||||
|
|
@ -137,7 +137,7 @@ struct NumberRec {
|
|||
|
||||
static halni getMaxIdx(const Buffer<halnf>& in) {
|
||||
halni out = 0;
|
||||
for (auto i : Range(in.size())) {
|
||||
for (auto i : IterRange(in.size())) {
|
||||
if (in[i] > in[out]) {
|
||||
out = i;
|
||||
}
|
||||
|
|
@ -165,15 +165,15 @@ struct NumberRec {
|
|||
void displayImage(ualni idx) {
|
||||
auto& testcase = mTestcases[idx];
|
||||
printf("Image : %i\n", int(getMaxIdx(testcase.output)));
|
||||
for (auto i : Range(28)) {
|
||||
for (auto j : Range(28)) {
|
||||
for (auto i : IterRange(28)) {
|
||||
for (auto j : IterRange(28)) {
|
||||
printf("%c", char(testcase.input[j * 28 + i] * 255));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
halnf test(const Range<halni>& range) {
|
||||
halnf test(const IterRange<halni>& range) {
|
||||
halnf avgCost = 0;
|
||||
for (auto i : range) {
|
||||
avgCost += eval(i);
|
||||
|
|
@ -182,7 +182,7 @@ struct NumberRec {
|
|||
return avgCost;
|
||||
}
|
||||
|
||||
void trainStep(const Range<halni>& range) {
|
||||
void trainStep(const IterRange<halni>& range) {
|
||||
nn.clearGrad();
|
||||
for (auto i : range) {
|
||||
nn.evaluate(mTestcases[i].input, output);
|
||||
|
|
@ -210,18 +210,19 @@ int main() {
|
|||
NumberRec app;
|
||||
|
||||
auto numBatches = 10;
|
||||
auto trainRange = Range(0, 50000);
|
||||
auto testRange = Range(50000, 70000);
|
||||
auto trainRange = IterRange(0, 50000);
|
||||
auto testRange = IterRange(50000, 70000);
|
||||
|
||||
auto batchSize = trainRange.idxDiff() / numBatches;
|
||||
|
||||
for (auto epoch : Range(1)) {
|
||||
for (auto epoch : IterRange(1)) {
|
||||
printf("Epoch %i\n", epoch.index());
|
||||
|
||||
for (auto batchIdx : Range(trainRange.idxDiff() / batchSize)) {
|
||||
for (auto batchIdx : IterRange(trainRange.idxDiff() / batchSize)) {
|
||||
printf(" - Batch :%i \n", batchIdx.index());
|
||||
|
||||
auto batchRange = Range(trainRange.idxBegin() + batchSize * batchIdx, trainRange.idxBegin() + batchSize * (batchIdx + 1));
|
||||
auto batchRange =
|
||||
IterRange(trainRange.idxBegin() + batchSize * batchIdx, trainRange.idxBegin() + batchSize * (batchIdx + 1));
|
||||
|
||||
app.trainStep(batchRange);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ void FCNN::initializeRandom(const Buffer<halni>& description) {
|
|||
|
||||
mLayers.reserve(description.size());
|
||||
|
||||
for (auto i : Range<halni>(0, (halni) description.size())) {
|
||||
for (auto i : IterRange<halni>(0, (halni) description.size())) {
|
||||
mLayers[i].neurons.reserve(description[i]);
|
||||
if (i == 0) {
|
||||
continue;
|
||||
|
|
@ -50,17 +50,17 @@ void FCNN::initializeRandom(const Buffer<halni>& description) {
|
|||
void FCNN::evaluate(const Buffer<halnf>& input, Buffer<halnf>& output) {
|
||||
ASSERT(output.size() == mLayers.last().neurons.size() && input.size() == mLayers.first().neurons.size())
|
||||
|
||||
for (auto idx : Range(input.size())) {
|
||||
for (auto idx : IterRange(input.size())) {
|
||||
mLayers.first().neurons[idx].activationValue = input[idx];
|
||||
}
|
||||
|
||||
for (auto layerIdx : Range<halni>(1, (halni) mLayers.size())) {
|
||||
for (auto layerIdx : IterRange<halni>(1, (halni) mLayers.size())) {
|
||||
auto& layer = mLayers[layerIdx];
|
||||
auto& layerPrev = mLayers[layerIdx - 1];
|
||||
|
||||
for (auto neuron : layer.neurons) {
|
||||
neuron->activationValue = 0;
|
||||
for (auto connectionIdx : Range(neuron->weights.size())) {
|
||||
for (auto connectionIdx : IterRange(neuron->weights.size())) {
|
||||
neuron->activationValue += neuron->weights[connectionIdx].val * layerPrev.neurons[connectionIdx].activationValue;
|
||||
}
|
||||
neuron->activationValue += neuron->bias.val;
|
||||
|
|
@ -69,26 +69,26 @@ void FCNN::evaluate(const Buffer<halnf>& input, Buffer<halnf>& output) {
|
|||
}
|
||||
}
|
||||
|
||||
for (auto idx : Range(output.size())) {
|
||||
for (auto idx : IterRange(output.size())) {
|
||||
output[idx] = mLayers.last().neurons[idx].activationValue;
|
||||
}
|
||||
}
|
||||
|
||||
halnf FCNN::calcCost(const Buffer<halnf>& output) {
|
||||
halnf out = 0;
|
||||
for (auto neuronIdx : Range(mLayers.last().neurons.size())) {
|
||||
for (auto neuronIdx : IterRange(mLayers.last().neurons.size())) {
|
||||
out += pow(output[neuronIdx] - mLayers.last().neurons[neuronIdx].activationValue, 2);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void FCNN::clearGrad() {
|
||||
for (auto layIdx : Range<halni>(1, (halni) mLayers.size())) {
|
||||
for (auto layIdx : IterRange<halni>(1, (halni) mLayers.size())) {
|
||||
auto& layer = mLayers[layIdx];
|
||||
|
||||
for (auto neuron : layer.neurons) {
|
||||
neuron->bias.grad = 0;
|
||||
for (auto weightIdx : Range(neuron->weights.size())) {
|
||||
for (auto weightIdx : IterRange(neuron->weights.size())) {
|
||||
neuron->weights[weightIdx].grad = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -102,7 +102,7 @@ void FCNN::calcGrad(const Buffer<halnf>& output) {
|
|||
auto& lastLayer = mLayers.last();
|
||||
|
||||
// calculate chaining cache value for each neuron in last layer
|
||||
for (auto neuronIdx : Range(lastLayer.neurons.size())) {
|
||||
for (auto neuronIdx : IterRange(lastLayer.neurons.size())) {
|
||||
auto& neuron = lastLayer.neurons[neuronIdx];
|
||||
neuron.cache = 2 * (neuron.activationValue - output[neuronIdx]);
|
||||
}
|
||||
|
|
@ -113,7 +113,7 @@ void FCNN::calcGrad(const Buffer<halnf>& output) {
|
|||
auto& currentLayer = mLayers[layerIdx];
|
||||
auto& inputLayer = mLayers[layerIdx - 1];
|
||||
|
||||
for (auto currentNeuronIdx : Range(currentLayer.neurons.size())) {
|
||||
for (auto currentNeuronIdx : IterRange(currentLayer.neurons.size())) {
|
||||
auto& currentNeuron = currentLayer.neurons[currentNeuronIdx];
|
||||
|
||||
// calculate cache value (chaining)
|
||||
|
|
@ -131,7 +131,7 @@ void FCNN::calcGrad(const Buffer<halnf>& output) {
|
|||
currentNeuron.bias.grad += currentNeuron.cache;
|
||||
|
||||
// calculate gradient for weights of current neuron
|
||||
for (auto weightIdx : Range(currentNeuron.weights.size())) {
|
||||
for (auto weightIdx : IterRange(currentNeuron.weights.size())) {
|
||||
currentNeuron.weights[weightIdx].grad += inputLayer.neurons[weightIdx].activationValue * currentNeuron.cache;
|
||||
}
|
||||
}
|
||||
|
|
@ -142,12 +142,12 @@ void FCNN::calcGrad(const Buffer<halnf>& output) {
|
|||
|
||||
void FCNN::applyGrad(halnf step) {
|
||||
|
||||
for (auto layIdx : Range<halni>(1, (halni) mLayers.size())) {
|
||||
for (auto layIdx : IterRange<halni>(1, (halni) mLayers.size())) {
|
||||
auto& layer = mLayers[layIdx];
|
||||
|
||||
for (auto neuron : layer.neurons) {
|
||||
neuron->bias.val -= neuron->bias.grad / (halnf) mAvgCount * step;
|
||||
for (auto weightIdx : Range(neuron->weights.size())) {
|
||||
for (auto weightIdx : IterRange(neuron->weights.size())) {
|
||||
neuron->weights[weightIdx].val -= (neuron->weights[weightIdx].grad / (halnf) mAvgCount) * step;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ SUITE(FCNN) {
|
|||
Buffer<halnf> outputExpected(layers.last());
|
||||
Buffer<halnf> output(layers.last());
|
||||
|
||||
for (auto inputVal : Range(layers.first())) {
|
||||
for (auto inputVal : IterRange(layers.first())) {
|
||||
input[inputVal] = inputLayer[inputVal];
|
||||
}
|
||||
|
||||
for (auto outIdx : Range(layers.last())) {
|
||||
for (auto outIdx : IterRange(layers.last())) {
|
||||
outputExpected[outIdx] = outputLayer[outIdx];
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ SUITE(FCNN) {
|
|||
|
||||
halnf cost = 0;
|
||||
|
||||
for (auto i : Range(150)) {
|
||||
for (auto i : IterRange(150)) {
|
||||
|
||||
nn.evaluate(input, output);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue