Skip to content

personalityson/VBANN

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

115 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VBANN

What is VBANN?

VBANN is a small machine learning framework implemented in VBA, which can be used to set up and train simple neural networks. I'm writing this project from scratch to deepen my understanding of neural networks.
VBANN is designed to store everything in the same file. Your training data, your model and the framework itself are all contained in the same workbook.
VBANN is modular and extensible. You can add your own layer classes.
You can speed it up 6-10x by downloading and linking to a prebuilt OpenBLAS dll inside the TensorOps module.

License

This project is licensed under the Creative Commons Zero v1.0 Universal.

Examples

Public Sub SetupAndTrain()
    Const MODEL_NAME As String = "MySequentialModel"
    Dim lBatchSize As Long
    Dim lNumEpochs As Long
    Dim lInputSize As Long
    Dim lLabelSize As Long
    Dim oFullSet As TensorDataset
    Dim oTrainingSet As SubsetDataset
    Dim oTrainingLoader As DataLoader
    Dim oTestSet As SubsetDataset
    Dim oTestLoader As DataLoader
    Dim oModel As Sequential

    lInputSize = 8
    lLabelSize = 1
    lBatchSize = 16
    lNumEpochs = 50

    'Prepare training data
    Set oFullSet = ImportDatasetFromWorksheet(ThisWorkbook, "Concrete", Array(lInputSize, lLabelSize), True, False)
    RandomSplit oFullSet, 0.8, oTrainingSet, oTestSet
    Set oTrainingLoader = DataLoader(oTrainingSet, lBatchSize)
    Set oTestLoader = DataLoader(oTestSet, lBatchSize)
    
    'Setup and train
    Set oModel = Sequential(L2Loss(), SGDM())
    oModel.Add InputNormalizationLayer(oTrainingLoader)
    oModel.Add FullyConnectedLayer(lInputSize, 64)
    oModel.Add LeakyReLULayer()
    oModel.Add FullyConnectedLayer(64, 16)
    oModel.Add LeakyReLULayer()
    oModel.Add FullyConnectedLayer(16, 4)
    oModel.Add LeakyReLULayer()
    oModel.Add FullyConnectedLayer(4, lLabelSize)
    oModel.Fit oTrainingLoader, oTestLoader, lNumEpochs

    'Compute test loss
    MsgBox oModel.Loss(oTestLoader)

    'Save to worksheet
    Serialize MODEL_NAME, oModel

    'Load from worksheet
    Set oModel = Unserialize(MODEL_NAME)

    'Compute test loss again with unserialized model
    MsgBox oModel.Loss(oTestLoader)

    Beep
End Sub

Public Function PredictInWorksheet(ByVal oInput As Range) As Variant
    Const MODEL_NAME As String = "MySequentialModel"
    Static s_oModel As Sequential
    Dim X As Tensor
    Dim Y As Tensor
    
    If s_oModel Is Nothing Then
        Set s_oModel = Unserialize(MODEL_NAME)
    End If
    Set X = TensorFromRange(oInput, True)
    Set Y = s_oModel.Predict(X)
    PredictInWorksheet = WorksheetFunction.Transpose(Y.ToArray)
End Function

Public Sub WorkingWithTensors()
    Dim A As Tensor
    Dim B As Tensor
    Dim A_() As Double
    Dim B_() As Double
    Dim adblArray() As Double

    'Create an empty tensor A filled with zeros, with shape (2, 3, 4).
    Set A = Zeros(Array(2, 3, 4))

    'Basic properties of A.
    MsgBox A.NumDimensions
    MsgBox A.Size(1)
    MsgBox A.Size(2)
    MsgBox A.Size(3)
    MsgBox A.NumElements
    MsgBox A.Address 'Pointer to the first element

    'Create a tensor A filled with constant values.
    Set A = Ones(Array(2, 3, 4))
    Set A = Full(Array(2, 3, 4), 777)

    'Create a tensor A filled with random values.
    Set A = Uniform(Array(2, 3, 4), 0, 1)
    Set A = Normal(Array(2, 3, 4), 0, 1)
    Set A = Bernoulli(Array(2, 3, 4), 0.5)

    'Fill tensor A with a constant value.
    A.Fill 777

    'Copy tensor A into a new tensor B. (B must be resized to match A's shape.)
    Set B = New Tensor
    B.Resize A.Shape
    B.Copy A

    'Clone tensor A into a new tensor B.
    Set B = A.Clone

    'Use ShapeEquals to check if A's shape matches (2, 3, 4).
    MsgBox A.ShapeEquals(Array(2, 3, 4))

    'Create a different view of A with a new shape (6, 4).
    'This view shares the same underlying data, but has a different layout.
    Set B = A.View(Array(6, 4))

    'Create alias arrays for direct memory access.
    A.CreateAlias A_
    B.CreateAlias B_

    ' Modify an element via the alias from A's perspective.
    A_(1, 1, 1) = 777

    'Both return 777.
    MsgBox A_(1, 1, 1)
    MsgBox B_(1, 1)

    'Erase the B_ alias to simulate clearing the fixed-size array.
    Erase B_

    'Both return 0.
    MsgBox A_(1, 1, 1)
    MsgBox B_(1, 1)

    'Remove the aliases to avoid memory deallocation.
    A.RemoveAlias A_
    B.RemoveAlias B_

    'Create a flattened view of A with shared underlying data. The new shape is (24).
    Set A = A.Flatten

    'Add singleton dimensions on both sides. The new shape is (1, 24, 1).
    Set A = A.View(Array(1, 24, 1))

    'Reshape A to a 2D tensor (4, 6). Number of elements must remain the same.
    A.Reshape Array(4, 6)

    'Reduce A along dimension 2 using mean reduction. The new shape is (4, 1).
    Set A = A.Reduce(2, rdcMean)

    'Slice A along dimension 1 from index 3 to 4. The new shape is (2, 1).
    Set A = A.Slice(1, 3, 4)

    'Tile A along dimension 2, repeating it 3 times. The new shape is (2, 3).
    Set A = A.Tile(2, 3)

    'Create tensor A from a native VBA array.
    A.FromArray adblArray

    'Copy tensor A to a native VBA array.
    adblArray = A.ToArray

    'Create tensor A from an Excel range.
    A.FromRange ActiveSheet.Range("A1:B3")
End Sub

Releases

No releases published

Packages

 
 
 

Contributors