Exploring Ruby’s Deep Learning Libraries: Building Neural Networks




In the vast landscape of programming languages for deep learning, Ruby might not be the first choice that comes to mind. However, with its user-friendly syntax and a growing ecosystem of libraries, Ruby is a viable option for building neural networks. In this blog, we will embark on a journey to explore Ruby’s deep learning capabilities and guide you through the process of building neural networks from scratch.
Table of Contents
Before we dive into the practical aspects, let’s address the question: Why Ruby for deep learning? While languages like Python are more commonly associated with deep learning due to their extensive libraries and frameworks, Ruby offers several advantages worth considering:
Ruby’s clean and expressive syntax makes it easy to read and write code. This can be a significant advantage when developing complex neural network architectures, as code readability is crucial for collaboration and maintenance.
Ruby is a versatile language with a rich ecosystem of gems (libraries) that can be leveraged for deep learning. While it may not have as many dedicated deep learning frameworks as Python, Ruby’s flexibility allows you to integrate with other libraries and tools seamlessly.
For developers already familiar with Ruby, there’s a natural inclination to explore its capabilities in the realm of deep learning. Using a language you’re comfortable with can accelerate the learning process.
Now that we’ve established the rationale behind using Ruby, let’s delve into the practical aspects.
Before we start building neural networks, it’s essential to set up a development environment. We’ll rely on two key Ruby gems: Numo and Daru.
Numo is a numerical computing library for Ruby that provides a NumPy-like interface for array operations. To install Numo, you can use the following command:
ruby gem install numo-narray
Daru is a data manipulation and analysis library for Ruby, similar to Pandas in Python. It’s helpful for preprocessing and handling datasets. Install Daru with:
ruby gem install daru
With Numo and Daru in place, we’re ready to begin our journey into deep learning.
In this section, we’ll build a simple feedforward neural network from scratch using Numo for array operations and Daru for data manipulation. Our goal is to create a basic neural network that can perform binary classification.
Let’s start by preparing our dataset. For this example, we’ll generate synthetic data. In practice, you would replace this with your own dataset.
ruby
require 'daru'
require 'numo/narray'
# Generate synthetic data
num_samples = 100
input_data = Numo::NArray.rand(num_samples, 2)
labels = input_data.sum(1) > 1.0 ? 1 : 0
# Create a Daru DataFrame
df = Daru::DataFrame.new({ feature1: input_data[0, true], feature2: input_data[1, true], label: labels })
# Split the data into training and testing sets
train_data, test_data = df.row[0..79], df.row[80..99]
In this code, we’ve generated random data with two features and assigned labels based on a simple condition. We’ve then created a Daru DataFrame and split it into training and testing sets.
Now, let’s define our neural network architecture. Our network will have an input layer, one hidden layer, and an output layer. We’ll use sigmoid activation for the hidden layer and a sigmoid output for binary classification.
ruby
class NeuralNetwork
def initialize(input_size, hidden_size)
@input_size = input_size
@hidden_size = hidden_size
@output_size = 1
# Initialize weights and biases
@weights_input_hidden = Numo::DFloat.new(@input_size, @hidden_size).rand
@biases_hidden = Numo::DFloat.new(@hidden_size).zeros
@weights_hidden_output = Numo::DFloat.new(@hidden_size, @output_size).rand
@biases_output = Numo::DFloat.new(@output_size).zeros
end
def sigmoid(x)
1 / (1 + Numo::NMath.exp(-x))
end
def forward(input)
# Input to hidden layer
@hidden_input = input.dot(@weights_input_hidden) + @biases_hidden
@hidden_output = sigmoid(@hidden_input)
# Hidden to output layer
@output = @hidden_output.dot(@weights_hidden_output) + @biases_output
@output
end
end
Here, we’ve defined the NeuralNetwork class with methods for initializing the network’s architecture, applying the sigmoid activation function, and performing the forward pass.
To train our neural network, we’ll use the backpropagation algorithm. We’ll define a loss function (mean squared error) and update the weights and biases using gradient descent.
ruby
class NeuralNetwork
# ... (previous code)
def mean_squared_error(predictions, targets)
((predictions - targets)**2).mean
end
def backward(input, target, learning_rate)
# Compute loss
loss = mean_squared_error(@output, target)
# Backpropagation
output_delta = 2 * (predictions - target)
hidden_delta = output_delta.dot(@weights_hidden_output.transpose) * @hidden_output * (1 - @hidden_output)
# Update weights and biases
@weights_hidden_output -= @hidden_output.transpose.dot(output_delta) * learning_rate
@biases_output -= output_delta.sum * learning_rate
@weights_input_hidden -= input.transpose.dot(hidden_delta) * learning_rate
@biases_hidden -= hidden_delta.sum * learning_rate
end
end
In this code, we’ve added methods for computing the mean squared error loss, performing backpropagation, and updating the weights and biases.
Now, let’s put it all together in a training loop.
ruby
# Initialize the neural network
input_size = 2
hidden_size = 4
learning_rate = 0.01
epochs = 1000
nn = NeuralNetwork.new(input_size, hidden_size)
# Training loop
epochs.times do |epoch|
train_data.each do |row|
input = row[:feature1..:feature2].to_a
target = Numo::NArray[row[:label]]
# Forward pass
predictions = nn.forward(input)
# Backpropagation and update
nn.backward(input, target, learning_rate)
end
# Calculate and print the loss for this epoch
train_loss = nn.mean_squared_error(nn.forward(train_data[:feature1..:feature2].to_a), train_data[:label].to_a)
puts "Epoch #{epoch + 1}/#{epochs}, Loss: #{train_loss}"
end
In this training loop, we iterate through the dataset, compute predictions, perform backpropagation, and update the weights and biases for a specified number of epochs.
Finally, let’s evaluate our trained neural network on the test data.
ruby
# Testing the model
test_loss = nn.mean_squared_error(nn.forward(test_data[:feature1..:feature2].to_a), test_data[:label].to_a)
puts "Test Loss: #{test_loss}"
This code calculates the mean squared error loss on the test data, providing an indication of the model’s performance.
In this blog, we’ve embarked on a journey to explore Ruby’s deep learning capabilities by building a neural network from scratch. While Ruby may not be as popular as Python for deep learning, its clean syntax, versatility, and a growing ecosystem of libraries make it a viable choice for certain projects.
As you delve deeper into the world of deep learning with Ruby, you’ll find that there are more libraries and tools at your disposal, such as the Numo-NumPy bridge for seamless integration with Python libraries. With dedication and creativity, you can harness the power of Ruby to develop robust neural networks and tackle a wide range of machine learning tasks.
Whether you’re a seasoned Rubyist or simply curious about expanding your programming horizons, exploring deep learning with Ruby can be a rewarding endeavor. So, go ahead, experiment, and build neural networks that pave the way for exciting AI applications in the Ruby ecosystem. Happy coding!
PythonJobs.ai is a specialized job board designed to connect Python developers with companies looking for talent. By focusing exclusively on Python-related roles, the platform provides a niche service tailored to a community with a specific skill set. However, for job seekers and employers, exploring alternatives to PythonJobs.ai is essential. Different job boards offer various features,...
AI Developers in the United States earn an average hourly rate of $62.19. The typical hourly range for this role spans from $50.96 to $75.48 per hour, highlighting the variance based on experience, skills, and other contributing factors in the industry. It is important to be aware of the current rates for the skill before...
In the United States, the average Shopify developer makes around $50 per hour, but the actual hourly rate can vary between $38 and $61. This variance is largely driven by factors such as the experience level of the developer and their geographical location. For example, senior Shopify developers who possess advanced skills and extensive experience...