Skip to content

Commit

Permalink
update v 1.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Dartrisen committed Aug 21, 2024
1 parent 882a921 commit 9292d65
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 71 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# CHANGELOG

## 1.0.1 (XX / XX / 2024)

#### Miscellaneous
- protocols `BinaryOperations` and `UnaryOperations` have been separated from the Value implementation
- project has been restructurized

## 1.0.0 (8 / 20 / 2024)

#### Features
- Value, Module, Neuron, Layer, MLP classes have been added
- **binary operations** : + - * /
- **unary operations** : tanh, exp
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
61 changes: 61 additions & 0 deletions Sources/SwiftGrad/Core/Value.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import Foundation

infix operator **: MultiplicationPrecedence

/// Represents a value in the computational graph, with support for automatic differentiation.
final class Value: CustomStringConvertible {
var data: Double
var grad: Double = 0.0
var _backward: () -> () = {}
var _prev: Set<Value>
var _op: String
var label: String

/// Initializes a new `Value` instance.
///
/// - Parameters:
/// - data: The scalar value.
/// - _children: The values that this `Value` depends on.
/// - _op: The operation that produced this value.
init(_ data: Double, _children: [Value] = [], _op: String = "", label: String = "") {
self.data = data
self._prev = Set(_children)
self._op = _op
self.label = label
}

var description: String {
return "Value(label: \(label), data: \(data), grad: \(grad))"
}

func backward() {
var topo: [Value] = []
var visited: Set<Value> = []

func buildTopo(_ v: Value) {
if !visited.contains(v) {
visited.insert(v)
for child in v._prev {
buildTopo(child)
}
topo.append(v)
}
}

buildTopo(self)
self.grad = 1.0
for v in topo.reversed() {
v._backward()
}
}
}

extension Value: Hashable {
static func == (lhs: Value, rhs: Value) -> Bool {
return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
}

func hash(into hasher: inout Hasher) {
hasher.combine(ObjectIdentifier(self))
}
}
Original file line number Diff line number Diff line change
@@ -1,79 +1,12 @@
import Foundation

infix operator **: MultiplicationPrecedence

/// Represents a value in the computational graph, with support for automatic differentiation.
final class Value: CustomStringConvertible, UnaryOperations {
var data: Double
var grad: Double = 0.0
var _backward: () -> () = {}
var _prev: Set<Value>
var _op: String
var label: String

init(_ data: Double, _children: [Value] = [], _op: String = "", label: String = "") {
self.data = data
self._prev = Set(_children)
self._op = _op
self.label = label
}

var description: String {
return "Value(label: \(label), data: \(data), grad: \(grad))"
}

func exp() -> Value {
let out = Value(Foundation.exp(data), _children: [self], _op: "exp")

out._backward = {
self.grad += out.data * out.grad
}
return out
}

func tanh() -> Value {
let t = Foundation.tanh(data)
let out = Value(t, _children: [self], _op: "tanh")
out._backward = { [weak self] in
guard let self = self else { return }
self.grad += (1 - t * t) * out.grad
}
return out
}

func backward() {
var topo: [Value] = []
var visited: Set<Value> = []

func buildTopo(_ v: Value) {
if !visited.contains(v) {
visited.insert(v)
for child in v._prev {
buildTopo(child)
}
topo.append(v)
}
}

buildTopo(self)
self.grad = 1.0
for v in topo.reversed() {
v._backward()
}
}
}

extension Value: Hashable {
static func == (lhs: Value, rhs: Value) -> Bool {
return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
}

func hash(into hasher: inout Hasher) {
hasher.combine(ObjectIdentifier(self))
}
enum ValueError: Error {
case divisionByZero
case invalidOperation(String)
}

extension Value: BinaryOperations {

static func + (lhs: Value, rhs: Value) -> Value {
let out = Value(lhs.data + rhs.data, _children: [lhs, rhs], _op: "+")
out._backward = { [weak lhs, weak rhs] in
Expand Down
27 changes: 27 additions & 0 deletions Sources/SwiftGrad/Extensions/Value+UnaryOperations.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Foundation

extension Value: UnaryOperations {

/// Applies the exponential function to a `Value` and returns a new `Value`.
///
/// - Returns: A new `Value` representing the result of `exp`.
func exp() -> Value {
let out = Value(Foundation.exp(self.data), _children: [self], _op: "exp")
out._backward = {
self.grad += out.data * out.grad
}
return out
}

/// Applies the hyperbolic tangent function to a `Value` and returns a new `Value`.
///
/// - Returns: A new `Value` representing the result of `tanh`.
func tanh() -> Value {
let t = Foundation.tanh(self.data)
let out = Value(t, _children: [self], _op: "tanh")
out._backward = { [weak self] in
self?.grad += (1 - t * t) * out.grad
}
return out
}
}
File renamed without changes.
File renamed without changes.

0 comments on commit 9292d65

Please sign in to comment.