Lesson · 40 min · Free
The Perceptron: Intro to Neural Networks
The Perceptron: Intro to Neural Networks body { font-family: sans-serif; line-height: 1.6; margin: 20px; } h1, h2 { color: #2c3e50; } pre { background-color: #ecf0f1; padding: 15px; border-radius: 5px; overflow-x: auto;
The Perceptron: Intro to Neural Networks
Welcome to this introductory lesson on neural networks, specifically focusing on the perceptron. While the field of artificial intelligence might seem distant from pharmaceutical research, the underlying principles of machine learning, including neural networks, are becoming increasingly vital. From predicting drug-target interactions to optimizing clinical trial design or analyzing complex genomic data, neural networks offer powerful tools for pattern recognition and prediction that can significantly accelerate and enhance pharmaceutical development. The perceptron, though a very simple model, is the foundational building block of more complex neural networks. Understanding its mechanics is crucial for grasping how these powerful algorithms learn from data. At its core, a perceptron is a binary classifier – it takes multiple binary (or real-valued) inputs, processes them, and outputs a single binary decision (e.g., 'yes' or 'no', 'active' or 'inactive'). Imagine a perceptron trying to decide if a new drug compound is likely to be effective. It would consider several inputs: the compound's molecular weight, its logP value, the presence of certain functional groups, etc. Each of these inputs is assigned a 'weight' which signifies its importance. The perceptron then calculates a weighted sum of these inputs. If this sum exceeds a certain 'threshold' (or bias), it activates, outputting a '1' (e.g., 'effective'); otherwise, it outputs '0' (e.g., 'ineffective').
The Anatomy of a Perceptron
Let's break down the mathematical representation of a perceptron. For a given set of inputs $x_1, x_2, \ldots, x_n$, and corresponding weights $w_1, w_2, \ldots, w_n$, the perceptron calculates an output $y$ as follows: $z = \sum_{i=1}^{n} (x_i \cdot w_i) + b$ where $b$ is the bias term. The output $y$ is then determined by an activation function, typically a step function for a classic perceptron: $y = \begin{cases} 1 & \text{if } z > 0 \\ 0 & \text{otherwise} \end{cases}$ The perceptron learns by adjusting its weights and bias. If its prediction is incorrect, it modifies the weights and bias slightly to try and reduce the error in the next iteration. This iterative adjustment is a key concept in machine learning. Let's implement a simple perceptron in Python. We'll start with a basic example that performs a logical AND operation. This means it should output 1 only when both inputs are 1, and 0 otherwise. import numpy as np class Perceptron: def __init__(self, num_inputs, learning_rate=0.01, epochs=100): self.weights = np.zeros(num_inputs) self.bias = 0 self.learning_rate = learning_rate self.epochs = epochs def _activate(self, x): # Step activation function return 1 if x > 0 else 0 def predict(self, inputs): # Calculate weighted sum + bias linear_output = np.dot(inputs, self.weights) + self.bias return self._activate(linear_output) def train(self, training_inputs, labels): for _ in range(self.epochs): for inputs, label in zip(training_inputs, labels): prediction = self.predict(inputs) # Update weights and bias based on error error = label - prediction self.weights += self.learning_rate * error * inputs self.bias += self.learning_rate * error # Training data for an AND gate # Input: [x1, x2], Output: y training_inputs = np.array([ [0, 0], [0, 1], [1, 0], [1, 1] ]) labels = np.array([0, 0, 0, 1]) # AND gate logic # Initialize and train the perceptron perceptron = Perceptron(num_inputs=2) perceptron.train(training_inputs, labels) # Test the trained perceptron print("Perceptron for AND gate:") print(f"0 AND 0: {perceptron.predict(np.array([0, 0]))}") print(f"0 AND 1: {perceptron.predict(np.array([0, 1]))}") print(f"1 AND 0: {perceptron.predict(np.array([1, 0]))}") print(f"1 AND 1: {perceptron.predict(np.array([1, 1]))}") The output of the above code demonstrates how the perceptron, after training, correctly classifies the AND logic. It learns the appropriate weights and bias to separate the input space into two regions: one where the output is 0 and another where it is 1. This ability to learn a decision boundary is fundamental. Now, let's consider a scenario more relevant to pharmaceutical research. Imagine we want to classify compounds as 'active' or 'inactive' based on two simplified features: 'molecular weight' (scaled) and 'hydrophobicity' (logP value). We'll simulate some data and train a perceptron. import numpy as np class Perceptron: def __init__(self, num_inputs, learning_rate=0.01, epochs=100): self.weights = np.zeros(num_inputs) self.bias = 0 self.learning_rate = learning_rate self.epochs = epochs def _activate(self, x): return 1 if x > 0 else 0 def predict(self, inputs): linear_output = np.dot(inputs, self.weights) + self.bias return self._activate(linear_output) def train(self, training_inputs, labels): for epoch in range(self.epochs): total_error = 0 for inputs, label in zip(training_inputs, labels): prediction = self.predict(inputs) error = label - prediction self.weights += self.learning_rate * error * inputs self.bias += self.learning_rate * error total_error += abs(error) # Optional: Print error every few epochs to see learning progress # if epoch % 10 == 0: # print(f"Epoch {epoch}, Total Error: {total_error}") if total_error == 0: # If no errors, perceptron has perfectly learned break # Simulated data for drug activity classification # Inputs: [scaled_molecular_weight, logP_value] # Output: 0 (inactive), 1 (active) # This data is linearly separable, which is a requirement for a simple perceptron drug_data_inputs = np.array([ [0.1, 0.5], # Low MW, moderate logP -> Inactive [0.2, 0.3], # Low MW, low logP -> Inactive [0.8, 0.9], # High MW, high logP -> Active [0.7, 0.7], # High MW, moderate logP -> Active [0.3, 0.6], # Moderate MW, moderate logP -> Inactive [0.9, 0.8], # High MW, high logP -> Active [0.15, 0.4] # Low MW, low logP -> Inactive ]) drug_data_labels = np.array([0, 0, 1, 1, 0, 1, 0]) # Initialize and train the perceptron for drug activity drug_perceptron = Perceptron(num_inputs=2, learning_rate=0.05, epochs=200) drug_perceptron.train(drug_data_inputs, drug_data_labels) # Test with new compounds print("\nPerceptron for Drug Activity Classification:") new_compounds = np.array([ [0.18, 0.45], # Expected Inactive [0.85, 0.92], # Expected Active [0.5, 0.6] # Expected Active (depending on decision boundary) ]) for i, compound in enumerate(new_compounds): prediction = drug_perceptron.predict(compound) status = "Active" if prediction == 1 else "Inactive" print(f"Compound {i+1} ({compound[0]:.2f} MW, {compound[1]:.2f} logP): Predicted {status}") print(f"\nFinal weights: {drug_perceptron.weights}") print(f"Final bias: {drug_perceptron.bias}") This example demonstrates how a perceptron can be applied to a simplified classification task in pharmaceutical research. It's important to note that the classic perceptron can only classify linearly separable data. This means there must be a straight line (or hyperplane in higher dimensions) that can perfectly separate the different classes. For more complex, non-linearly separable data, multi-layer perceptrons (which are the basis of deep neural networks) are required.
Key Takeaways
The perceptron is the simplest form of a neural network, acting as a binary classifier. It takes weighted inputs, sums them, adds a bias, and applies an activation function (typically a step function). Learning occurs by iteratively adjusting weights and bias based on prediction errors. Perceptrons can only classify linearly separable data. Understanding perceptrons provides a foundational understanding for more complex neural network architectures used in modern AI.
Practice Exercise
Modify the Perceptron class from the drug activity example. Instead of a simple step function, implement a sigmoid activation function: $f(x) = \frac{1}{1 + e^{-x}}$. Note that for a sigmoid, the output is a probability between 0 and 1. You'll need to decide on a threshold (e.g., 0.5) to convert this probability back into a binary 0 or 1 classification for prediction. How does this change the training dynamics or the final weights/bias? (Hint: The error calculation might need slight adjustment if you want the perceptron to perfectly converge for linearly separable data, but for this exercise, focus on just changing the activation and thresholding the output.)
Watch the full lesson — free
This topic is part of Python for Pharmaceutical Research, a complete AI-narrated video course. Press play once and watch the entire lecture like a movie.
Start the course free →