diff options
author | makefunstuff <[email protected]> | 2024-07-11 00:05:11 +0200 |
---|---|---|
committer | makefunstuff <[email protected]> | 2024-07-11 00:05:11 +0200 |
commit | fd3a727f4b4f819178225cdd87d8788b85c4b86c (patch) | |
tree | 58c6ee139f7768ec739477354af0faf001b2d40d | |
parent | e5a064e82fe7d36f4423abdf798f9f1f0a90ae0e (diff) | |
download | tinkerbunk-fd3a727f4b4f819178225cdd87d8788b85c4b86c.tar.gz |
some fixes and dummy neuron
-rw-r--r-- | build.zig | 5 | ||||
-rw-r--r-- | src/monkey_brain/multi_layer_perceptron.zig | 0 | ||||
-rw-r--r-- | src/monkey_brain/neural_network/layer.zig | 5 | ||||
-rw-r--r-- | src/monkey_brain/neural_network/neuron.zig | 56 | ||||
-rw-r--r-- | src/monkey_brain/perceptron.zig | 16 | ||||
-rw-r--r-- | src/monkey_brain/test.zig | 9 |
6 files changed, 80 insertions, 11 deletions
diff --git a/build.zig b/build.zig index aea990e..9b16a14 100644 --- a/build.zig +++ b/build.zig @@ -23,10 +23,9 @@ fn define_subproj(name: []const u8, b: *std.Build, target: std.Build.ResolvedTar run_step.dependOn(&run_cmd.step); const test_exe = b.addTest(.{ .root_source_file = b.path(test_path), .target = target, .optimize = optimize }); - - const test_cmd = b.addRunArtifact(test_exe); + const run_unit_tests = b.addRunArtifact(test_exe); const test_step = b.step(test_task_name, test_task_desc); - test_step.dependOn(&test_cmd.step); + test_step.dependOn(&run_unit_tests.step); } pub fn build(b: *std.Build) !void { diff --git a/src/monkey_brain/multi_layer_perceptron.zig b/src/monkey_brain/multi_layer_perceptron.zig deleted file mode 100644 index e69de29..0000000 --- a/src/monkey_brain/multi_layer_perceptron.zig +++ /dev/null diff --git a/src/monkey_brain/neural_network/layer.zig b/src/monkey_brain/neural_network/layer.zig new file mode 100644 index 0000000..7b2bf6e --- /dev/null +++ b/src/monkey_brain/neural_network/layer.zig @@ -0,0 +1,5 @@ +const std = @import("std"); +const math = std.math; +const Random = std.Random; +const ArrayList = std.ArrayList; +const testing = std.testing; diff --git a/src/monkey_brain/neural_network/neuron.zig b/src/monkey_brain/neural_network/neuron.zig new file mode 100644 index 0000000..a26b787 --- /dev/null +++ b/src/monkey_brain/neural_network/neuron.zig @@ -0,0 +1,56 @@ +const std = @import("std"); +const math = std.math; +const Random = std.Random; +const ArrayList = std.ArrayList; +const testing = std.testing; + +pub const Neuron = struct { + weights: ArrayList(f64), + bias: f64, + + pub fn init(allocator: std.mem.Allocator, num_inputs: usize) !Neuron { + var weights = ArrayList(f64).init(allocator); + var prng = Random.DefaultPrng.init(blk: { + const seed: u64 = @intCast(std.time.milliTimestamp()); + break :blk seed; + }); + + var random = prng.random(); + var i: usize = 0; + + while (i < num_inputs) : (i += 1) { + try weights.append(random.float(f64) * 2 - 1); + } + + return Neuron{ + .weights = weights, + .bias = random.float(f64) * 2 - 1, + }; + } + + pub fn deinit(self: *Neuron) void { + self.weights.deinit(); + } + + pub fn activate(self: *const Neuron, inputs: []const f64) f64 { + var sum: f64 = self.bias; + for (self.weights.items, 0..) |weight, i| { + sum += inputs[i] * weight; + } + return sigmoid(sum); + } +}; + +fn sigmoid(x: f64) f64 { + return 1.0 / (1.0 + math.exp(-x)); +} + +test "Neuron initialization" { + const allocator = testing.allocator; + var neuron = try Neuron.init(allocator, 2); + defer neuron.deinit(); + + std.debug.print("Testing neuron", .{}); + try testing.expect(neuron.weights.items.len == 2); + try testing.expect(neuron.bias >= -1 and neuron.bias <= 1); +} diff --git a/src/monkey_brain/perceptron.zig b/src/monkey_brain/perceptron.zig index 893bb16..1d819d1 100644 --- a/src/monkey_brain/perceptron.zig +++ b/src/monkey_brain/perceptron.zig @@ -5,7 +5,7 @@ const math = std.math; const input_size: usize = 2; const training_set_size: usize = 4; const learning_rate: f64 = 0.1; -const epochs: u64 = 1000000; +const epochs: u64 = 10000; // https://en.wikipedia.org/wiki/Sigmoid_function - more details // https://www.youtube.com/watch?v=TPqr8t919YM @@ -40,8 +40,8 @@ fn train(weights: *[input_size]f64, bias: *f64, training_data: [training_set_siz } pub fn demo() !void { - var weights = [_]f64{ std.crypto.random.float(f64), std.crypto.random.float(f64) }; - var bias: f64 = std.crypto.random.float(f64); + var weights = [_]f64{ std.crypto.random.float(f64) * 2 - 1, std.crypto.random.float(f64) * 2 - 1 }; + var bias: f64 = std.crypto.random.float(f64) * 2 - 1; const training_data = [_][input_size]f64{ .{ 0, 0 }, @@ -63,8 +63,8 @@ pub fn demo() !void { } test "OR gate" { - var weights = [_]f64{ 0, 0 }; - var bias: f64 = 0; + var weights = [_]f64{ 0.3, 0.2 }; + var bias: f64 = 0.5; const training_data = [_][input_size]f64{ .{ 0, 0 }, @@ -78,6 +78,10 @@ test "OR gate" { for (training_data, labels) |inputs, expected| { const prediction = predict(weights, bias, inputs); - try testing.expect((prediction - expected) < 0.1); + const predicted_error = prediction - expected; + std.debug.print("Predicted error {}\n", .{predicted_error}); + std.debug.print("Predicted: {} | Expected: {}\n", .{ prediction, expected }); + + try testing.expect(predicted_error < 0.1); } } diff --git a/src/monkey_brain/test.zig b/src/monkey_brain/test.zig index b3363e9..dd14718 100644 --- a/src/monkey_brain/test.zig +++ b/src/monkey_brain/test.zig @@ -1,3 +1,8 @@ -comptime { - _ = @import("perceptron.zig"); +const std = @import("std"); +const testing = std.testing; +pub const perceptron = @import("perceptron.zig"); +pub const neuron = @import("neural_network/neuron.zig"); + +test { + testing.refAllDeclsRecursive(@This()); } |