-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
Samuel Abramov
committed
Oct 15, 2023
1 parent
4c7c25b
commit 0db5f89
Showing
17 changed files
with
1,063 additions
and
48 deletions.
There are no files selected for viewing
29 changes: 29 additions & 0 deletions
29
example/src/main/java/de/example/cnn/ConvolutionalNeuralNetworkExample.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package de.example.cnn; | ||
|
||
import de.edux.api.Classifier; | ||
import de.edux.ml.cnn.*; | ||
|
||
public class ConvolutionalNeuralNetworkExample { | ||
final static int NUM_CLASSES = 1000; | ||
|
||
public static void main(String[] args) { | ||
Classifier alexNet = new Architect.Builder() | ||
.addLayer(new ConvLayer(11, 11, 3, 96, 4, 0)) // 1. Convolutional Layer | ||
.addLayer(new MaxPoolingLayer(3, 3, 2)) // 1. Max-Pooling Layer | ||
.addLayer(new ConvLayer(5, 5, 96, 256, 1, 2)) // 2. Convolutional Layer | ||
.addLayer(new MaxPoolingLayer(3, 3, 2)) // 2. Max-Pooling Layer | ||
.addLayer(new ConvLayer(3, 3, 256, 384, 1, 1)) // 3. Convolutional Layer | ||
.addLayer(new ConvLayer(3, 3, 384, 384, 1, 1)) // 4. Convolutional Layer | ||
.addLayer(new ConvLayer(3, 3, 384, 256, 1, 1)) // 5. Convolutional Layer | ||
.addLayer(new MaxPoolingLayer(3, 3, 2)) // 3. Max-Pooling Layer | ||
.addLayer(new FlattenLayer()) // Flattening Layer | ||
.addLayer(new DenseLayer(4096)) // 1. Fully Connected (Dense) Layer | ||
.addLayer(new DropOutLayer(0.5)) // 1. Dropout Layer | ||
.addLayer(new DenseLayer(4096)) // 2. Fully Connected (Dense) Layer | ||
.addLayer(new DropOutLayer(0.5)) // 2. Dropout Layer | ||
.addLayer(new DenseLayer(NUM_CLASSES)) // 3. Fully Connected (Dense) Layer | ||
.build(); | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package de.edux.functions.optimizer; | ||
|
||
public enum Optimizer { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package de.edux.ml.cnn; | ||
|
||
import de.edux.api.Classifier; | ||
|
||
public class Architect { | ||
|
||
|
||
|
||
public static class Builder { | ||
|
||
public Builder addLayer(Layer layer) { | ||
return this; | ||
} | ||
public Classifier build() { | ||
return null; | ||
} | ||
} | ||
} |
106 changes: 106 additions & 0 deletions
106
lib/src/main/java/de/edux/ml/cnn/AveragePoolingLayer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package de.edux.ml.cnn; | ||
|
||
import de.edux.functions.optimizer.Optimizer; | ||
|
||
public class AveragePoolingLayer implements Layer { | ||
private int poolSize; | ||
private int stride; | ||
|
||
public AveragePoolingLayer(int poolSize, int stride) { | ||
this.poolSize = poolSize; | ||
this.stride = stride; | ||
} | ||
|
||
@Override | ||
public ITensor forward(ITensor input) { | ||
// Größenangaben des Eingabesensors bestimmen | ||
int[] inputShape = input.getShape(); | ||
int height = inputShape[0]; | ||
int width = inputShape[1]; | ||
int channels = inputShape[2]; | ||
|
||
// Größenangaben des Ausgabesensors bestimmen | ||
int pooledHeight = (height - poolSize) / stride + 1; | ||
int pooledWidth = (width - poolSize) / stride + 1; | ||
|
||
ITensor output = new Tensor(pooledHeight, pooledWidth, channels); | ||
|
||
for (int h = 0; h < pooledHeight; h++) { | ||
for (int w = 0; w < pooledWidth; w++) { | ||
for (int c = 0; c < channels; c++) { | ||
double sum = 0; | ||
for (int i = 0; i < poolSize; i++) { | ||
for (int j = 0; j < poolSize; j++) { | ||
sum += input.get(h * stride + i, w * stride + j, c); | ||
} | ||
} | ||
double average = sum / (poolSize * poolSize); | ||
output.set(average, h, w, c); | ||
} | ||
} | ||
} | ||
|
||
return output; | ||
} | ||
|
||
@Override | ||
public ITensor backward(ITensor gradient) { | ||
// Größenangaben des Gradiententensors bestimmen | ||
int[] gradientShape = gradient.getShape(); | ||
int height = gradientShape[0]; | ||
int width = gradientShape[1]; | ||
int channels = gradientShape[2]; | ||
|
||
ITensor dInput = new Tensor(height * stride, width * stride, channels); | ||
|
||
for (int h = 0; h < height; h++) { | ||
for (int w = 0; w < width; w++) { | ||
for (int c = 0; c < channels; c++) { | ||
double gradientValue = gradient.get(h, w, c) / (poolSize * poolSize); | ||
for (int i = 0; i < poolSize; i++) { | ||
for (int j = 0; j < poolSize; j++) { | ||
dInput.set(gradientValue, h * stride + i, w * stride + j, c); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
return dInput; | ||
} | ||
|
||
@Override | ||
public void initializeWeights() { | ||
|
||
} | ||
|
||
@Override | ||
public void updateWeights(Optimizer optimizer) { | ||
|
||
} | ||
|
||
@Override | ||
public ITensor getWeights() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public void setWeights(ITensor weights) { | ||
|
||
} | ||
|
||
@Override | ||
public ITensor getBiases() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public void setBiases(ITensor biases) { | ||
|
||
} | ||
|
||
@Override | ||
public boolean isTrainable() { | ||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package de.edux.ml.cnn; | ||
|
||
import de.edux.functions.optimizer.Optimizer; | ||
|
||
|
||
public class ConvLayer implements Layer { | ||
private ITensor filters; // Der Filter-Tensor: [filterHeight, filterWidth, inputChannels, outputChannels] | ||
private ITensor biases; // Optional, je nach Architektur | ||
private int stride; | ||
private int padding; | ||
|
||
public ConvLayer(int filterHeight, int filterWidth, int inputChannels, int outputChannels, int stride, int padding) { | ||
this.stride = stride; | ||
this.padding = padding; | ||
this.filters = new Tensor(filterHeight, filterWidth, inputChannels, outputChannels); | ||
this.biases = new Tensor(1, 1, 1, outputChannels); // 1x1 bias für jeden Ausgabekanal | ||
initializeWeights(); | ||
} | ||
|
||
@Override | ||
public ITensor forward(ITensor input) { | ||
// ... Ihre bisherige Implementierung .. | ||
return null; | ||
} | ||
|
||
@Override | ||
public ITensor backward(ITensor gradient) { | ||
// ... Ihre bisherige Implementierung ... | ||
return null; | ||
} | ||
|
||
@Override | ||
public void initializeWeights() { | ||
// 1. Xavier/Glorot-Initialisierung (als Beispiel): | ||
// Dies ist eine grobe Implementierung; Sie könnten eine spezielle Methode in Ihrem Tensor oder eine Utility-Methode verwenden, um dies effizient zu tun. | ||
int fanIn = filters.getShape()[2]; // Anzahl der Eingangskanäle | ||
int fanOut = filters.getShape()[3]; // Anzahl der Ausgangskanäle | ||
double variance = 2.0 / (fanIn + fanOut); | ||
double scale = Math.sqrt(variance); | ||
|
||
for (int i = 0; i < filters.getTotalSize(); i++) { | ||
double weight = (Math.random() * 2 - 1) * scale; // Zufällige Initialisierung im Bereich [-scale, scale] | ||
filters.setValueAt(i, weight); | ||
} | ||
|
||
// Biases auf 0 setzen (üblich bei Conv-Layern) | ||
for (int i = 0; i < biases.getTotalSize(); i++) { | ||
biases.setValueAt(i, 0.0); | ||
} | ||
} | ||
|
||
@Override | ||
public void updateWeights(Optimizer optimizer) { | ||
// ... Ihre bisherige Implementierung ... | ||
} | ||
|
||
@Override | ||
public ITensor getWeights() { | ||
return filters; | ||
} | ||
|
||
@Override | ||
public void setWeights(ITensor weights) { | ||
this.filters = weights; | ||
} | ||
|
||
@Override | ||
public ITensor getBiases() { | ||
return biases; | ||
} | ||
|
||
@Override | ||
public void setBiases(ITensor biases) { | ||
this.biases = biases; | ||
} | ||
|
||
@Override | ||
public boolean isTrainable() { | ||
return true; // Faltungsschichten sind in der Regel trainierbar | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
lib/src/main/java/de/edux/ml/cnn/ConvolutionalNeuralNetwork.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package de.edux.ml.cnn; | ||
|
||
import de.edux.api.Classifier; | ||
|
||
public class ConvolutionalNeuralNetwork implements Classifier { | ||
@Override | ||
public boolean train(double[][] features, double[][] labels) { | ||
return false; | ||
} | ||
|
||
@Override | ||
public double evaluate(double[][] testInputs, double[][] testTargets) { | ||
return 0; | ||
} | ||
|
||
@Override | ||
public double[] predict(double[] feature) { | ||
return new double[0]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package de.edux.ml.cnn; | ||
|
||
import de.edux.functions.optimizer.Optimizer; | ||
|
||
public class DenseLayer implements Layer { | ||
|
||
public DenseLayer(int inputSize, int outputSize) { | ||
} | ||
|
||
public DenseLayer(int numberOfClasses) { | ||
} | ||
|
||
@Override | ||
public ITensor forward(ITensor input) { | ||
return null; | ||
} | ||
|
||
@Override | ||
public ITensor backward(ITensor gradient) { | ||
return null; | ||
} | ||
|
||
@Override | ||
public void initializeWeights() { | ||
|
||
} | ||
|
||
@Override | ||
public void updateWeights(Optimizer optimizer) { | ||
|
||
} | ||
|
||
@Override | ||
public ITensor getWeights() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public void setWeights(ITensor weights) { | ||
|
||
} | ||
|
||
@Override | ||
public ITensor getBiases() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public void setBiases(ITensor biases) { | ||
|
||
} | ||
|
||
@Override | ||
public boolean isTrainable() { | ||
return false; | ||
} | ||
} |
Oops, something went wrong.