{"id":14235522,"url":"https://github.com/xlisp/visualization-machine-learning","last_synced_at":"2025-04-28T13:47:23.698Z","repository":{"id":127744474,"uuid":"95839726","full_name":"xlisp/visualization-machine-learning","owner":"xlisp","description":"Visualization Python \u0026 R Machine Learning, Deep Learning, Reinforcement Learning","archived":false,"fork":false,"pushed_at":"2024-12-15T03:33:40.000Z","size":57018,"stargazers_count":22,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-15T00:05:03.487Z","etag":null,"topics":["deep-learning","machine-learning","python","pytorch","r","reinforcement-learning","statistics"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xlisp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-30T02:29:33.000Z","updated_at":"2025-02-01T18:55:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"a7a2c0a7-860a-4b10-918f-8decd00a6a91","html_url":"https://github.com/xlisp/visualization-machine-learning","commit_stats":null,"previous_names":["chanshunli/jim-emacs-machine-learning","xlisp/machine-learning","xlisp/visualization-machine-learning"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xlisp%2Fvisualization-machine-learning","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xlisp%2Fvisualization-machine-learning/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xlisp%2Fvisualization-machine-learning/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xlisp%2Fvisualization-machine-learning/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xlisp","download_url":"https://codeload.github.com/xlisp/visualization-machine-learning/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251191493,"owners_count":21550140,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deep-learning","machine-learning","python","pytorch","r","reinforcement-learning","statistics"],"created_at":"2024-08-20T21:02:02.136Z","updated_at":"2025-04-28T13:47:23.642Z","avatar_url":"https://github.com/xlisp.png","language":"Python","funding_links":[],"categories":["R"],"sub_categories":[],"readme":"# Visualization Python \u0026 R Machine Learning, Deep Learning, Reinforcement Learning\n\n## First principle\n\n* Find the same probability distribution in a large amount of data and make predictions based on the same probability distribution: `y = f(x)`\n* Just like learning a function relationship, the inverse function or reverse engineering function requires DL. You just know that the data has a certain pattern and then guess what the original function that generated the data is. For example, you train to get a calculator neural network.\n* The idea of high-dimensional space: the code is cut into high-dimensional space, and then a very detailed high-dimensional classification is done to separate it. Then the search is also high-dimensional, just like the code, it is entered into the treesitter to do training to obtain logical learning relationships. Most of NLP is a multi-classification problem in high-dimensional space.\n* Collect the input x and output y around you as training data, and mine their mapping relationship f(x) at any time. You can use GPT to generate certain data for your model training needs or write crawler to get you need data.\n\n- [Python \u0026 R Machine Learning](#python--r-machine-learning)\n  - [R Machine Learning](https://github.com/chanshunli/jim-emacs-machine-learning/tree/master/R-Lang-machine-learning)\n  - [least squares method](#least-squares-method)\n  - [least squares method by neural network](#least-squares-method-by-neural-network)\n  - [nonlinear fitting](#nonlinear-fitting)\n  - [polar coordinate classification](#polar-coordinate-classification)\n  - [mnist ocr](#mnist-ocr)\n  - [use mnist](#use-mnist)\n  - [calculator neural network](#calculator-neural-network)\n  - [Data cleaning](#data-cleaning)\n  - [SVM](#svm)\n  - [kmeans](#kmeans)\n  - [Decision Tree Classifier](#decision-tree-classifier)\n  - [Reinforcement Learning (DQN)](#reinforcement-learning-dqn)\n  - [Flappy bird dqn](#flappy-bird-dqn)\n  - [SGD](#sgd)\n  - [CNN with Attention](#CNN-with-Attention)\n  - [LSTM generator](#LSTM-generator)\n  - [Seq2seq number translator](#seq2seq-number-translator)\n  - [Transformer generator](#Transformer-generator)\n\n## init env\n\n```bash\nconda create -n emacspy python=3.11\nconda activate emacspy\npoetry install\n```\n\n## least squares method\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# Example data points\nX = np.array([1, 2.2, 3, 4, 5])\ny = np.array([2, 4, 6.3, 8, 11])\n\n# Add a column of ones to X for the intercept term (bias)\nX_b = np.c_[np.ones((X.shape[0], 1)), X]  # X_b is X with a bias column\n\n# Calculate the best fit line parameters using the Normal Equation\ntheta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)\n\n# Print the parameters (intercept and slope)\nprint(f\"Intercept: {theta_best[0]}\")\nprint(f\"Slope: {theta_best[1]}\")\n\n# Predict values using the model\ny_pred = X_b.dot(theta_best)\n\n# Plot the data points and the best fit line\nplt.scatter(X, y, color='blue', label='Data points')\nplt.plot(X, y_pred, color='red', label='Best fit line')\nplt.xlabel('X')\nplt.ylabel('y')\nplt.legend()\nplt.show()\n```\n\n## least squares method by neural network\n\n![](./training_animation.gif)\n\n```python\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport matplotlib.pyplot as plt\n\n# graph show the  pytorch torch.optim.Adam and plot it How it works\n\n# Define a simple linear model\nclass LinearModel(nn.Module):\n    def __init__(self):\n        super(LinearModel, self).__init__()\n        self.linear = nn.Linear(1, 1)\n\n    def forward(self, x):\n        return self.linear(x)\n\n# Initialize the model, loss function, and optimizer\nmodel = LinearModel()\ncriterion = nn.MSELoss()\noptimizer = optim.Adam(model.parameters(), lr=0.01)\n\n# Generate some synthetic data (y = 2x + 1 with some noise)\nx_train = torch.linspace(-1, 1, 100).reshape(-1, 1)\ny_train = 2 * x_train + 1 + 0.2 * torch.randn(x_train.size())\n\n# List to store the loss values\nloss_values = []\n\n# Training loop\nfor epoch in range(1000):\n    model.train()\n    optimizer.zero_grad()\n    outputs = model(x_train)\n    loss = criterion(outputs, y_train)\n    loss.backward()\n    optimizer.step()\n    loss_values.append(loss.item())\n```\n\n## nonlinear fitting\n\n![](./training_process.gif)\n\n\u003cimg src=\"2013_nonlinear_fitting.png\" width=\"500\" \u003e\n\n```python\nimport torch\nimport torch.nn as nn\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# Step 1: Generate a 100-length random sequence\nn = 100\nx = torch.linspace(1, 10, n).unsqueeze(1)\ny = torch.sin(x) + torch.rand(n, 1) * 0.5\n\n# Step 2: Define a simple neural network model for nonlinear fitting\nclass NonlinearModel(nn.Module):\n    def __init__(self):\n        super(NonlinearModel, self).__init__()\n        self.fc1 = nn.Linear(1, 10)\n        self.fc2 = nn.Linear(10, 10)\n        self.fc3 = nn.Linear(10, 1)\n\n    def forward(self, x):\n        x = torch.relu(self.fc1(x))\n        x = torch.relu(self.fc2(x))\n        x = self.fc3(x)\n        return x\n\nmodel = NonlinearModel()\n\n# Step 3: Define loss function and optimizer\ncriterion = nn.MSELoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=0.01)\n\n# Step 4: Train the model\nepochs = 1000\nfor epoch in range(epochs):\n    model.train()\n\n    # Forward pass\n    outputs = model(x)\n    loss = criterion(outputs, y)\n\n    # Backward pass and optimization\n    optimizer.zero_grad()\n    loss.backward()\n    optimizer.step()\n\n    if (epoch+1) % 100 == 0:\n        print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')\n\n# Step 5: Plot the original data and the fitted curve\nmodel.eval()\nwith torch.no_grad():\n    predicted = model(x).numpy()\n\nplt.figure(figsize=(10, 5))\nplt.plot(x.numpy(), y.numpy(), 'ro', label='Original data')\nplt.plot(x.numpy(), predicted, 'b-', label='Fitted curve')\nplt.legend()\nplt.show()\n\n```\n## polar coordinate classification\n\u003cimg src=\"polar_coordinate_classification.gif\" width=\"500\" \u003e\n\n```python\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader, TensorDataset\nimport matplotlib.pyplot as plt\nfrom mpl_toolkits.mplot3d import Axes3D\n\n# Helper function to convert Cartesian to Polar coordinates\ndef cartesian_to_polar(x, y, z):\n    r = torch.sqrt(x**2 + y**2 + z**2)\n    theta = torch.atan2(y, x)\n    phi = torch.acos(z / r)\n    return r, theta, phi\n\n# Example data generation (replace with your actual data)\nn_samples = 5000\nx = torch.randn(n_samples)\ny = torch.randn(n_samples)\nz = torch.randn(n_samples)\nlabels = torch.randint(0, 4, (n_samples,))  # Four classes (0, 1, 2, 3)\n\n# Convert to polar coordinates\nr, theta, phi = cartesian_to_polar(x, y, z)\n\n# Combine into a single tensor\ndata = torch.stack((r, theta, phi), dim=1)\n\n# Create a Dataset and DataLoader\ndataset = TensorDataset(data, labels)\ntrain_loader = DataLoader(dataset, batch_size=32, shuffle=True)\n\n# Define a simple feedforward neural network\nclass PolarNet(nn.Module):\n    def __init__(self):\n        super(PolarNet, self).__init__()\n        self.fc1 = nn.Linear(3, 64)\n        self.fc2 = nn.Linear(64, 128)\n        self.fc3 = nn.Linear(128, 4)  # Four output classes\n\n    def forward(self, x):\n        x = torch.relu(self.fc1(x))\n        x = torch.relu(self.fc2(x))\n        x = self.fc3(x)\n        return x\n\n# Initialize the model, loss function, and optimizer\nmodel = PolarNet()\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)\n\n# Training loop\nfor epoch in range(20):  # Number of epochs\n    for inputs, targets in train_loader:\n        # Forward pass\n        outputs = model(inputs)\n        loss = criterion(outputs, targets)\n\n        # Backward pass and optimization\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n    print(f'Epoch {epoch+1}/20, Loss: {loss.item()}')\n\n# After training, evaluate the model on the entire dataset for visualization\nwith torch.no_grad():\n    predicted_labels = model(data).argmax(dim=1)\n\n# Plotting the results in 3D\nfig = plt.figure()\nax = fig.add_subplot(111, projection='3d')\n\n# Convert polar back to Cartesian for plotting\nx_cartesian = r * torch.sin(phi) * torch.cos(theta)\ny_cartesian = r * torch.sin(phi) * torch.sin(theta)\nz_cartesian = r * torch.cos(phi)\n\n# Plot the 3D scatter plot\nscatter = ax.scatter(x_cartesian, y_cartesian, z_cartesian, c=predicted_labels, cmap='viridis', marker='o')\n\n# Add color bar and labels\nplt.colorbar(scatter, ax=ax)\nax.set_xlabel('X')\nax.set_ylabel('Y')\nax.set_zlabel('Z')\nplt.title('3D Visualization of PolarNet Classifications')\nplt.show()\n```\n\n## mnist ocr\n\n```python\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nfrom torchvision import datasets, transforms\nfrom torch.utils.data import DataLoader\n\nbatch_size = 64\nlearning_rate = 0.01\nepochs = 100\ntransform = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize((0.1307,), (0.3081,))\n])\ntrain_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)\ntest_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)\ntrain_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)\ntest_loader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)\n\nclass Net(nn.Module):\n    def __init__(self):\n        super(Net, self).__init__()\n        self.fc1 = nn.Linear(28 * 28, 128)\n        self.fc2 = nn.Linear(128, 64)\n        self.fc3 = nn.Linear(64, 10)\n\n    def forward(self, x):\n        x = x.view(-1, 28 * 28)\n        x = F.relu(self.fc1(x))\n        x = F.relu(self.fc2(x))\n        x = self.fc3(x)\n        return x\n\nmodel = Net()\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.SGD(model.parameters(), lr=learning_rate)\n\nfor epoch in range(epochs):\n    model.train()\n    for batch_idx, (data, target) in enumerate(train_loader):\n        optimizer.zero_grad()\n        output = model(data)\n        loss = criterion(output, target)\n        loss.backward()\n        optimizer.step()\n        if batch_idx % 100 == 0:\n            print(f'Epoch: {epoch+1}/{epochs} [Batch: {batch_idx*len(data)}/{len(train_loader.dataset)}] Loss: {loss.item():.6f}')\n\nmodel.eval()\ntest_loss = 0\ncorrect = 0\n\nwith torch.no_grad():\n    for data, target in test_loader:\n        output = model(data)\n        test_loss += criterion(output, target).item()\n        pred = output.argmax(dim=1, keepdim=True)\n        correct += pred.eq(target.view_as(pred)).sum().item()\n\ntest_loss /= len(test_loader.dataset)\naccuracy = 100. * correct / len(test_loader.dataset)\nprint(f'Test set: Average loss: {test_loss:.4f}, Accuracy: {correct}/{len(test_loader.dataset)} ({accuracy:.2f}%)')\ntorch.save(model.state_dict(), \"mnist_model.pth\")\n\n```\n## use mnist\n\n```python\nmodel = Net()\n### 3. Load the Trained Model Weights\nmodel.load_state_dict(torch.load(\"mnist_model.pth\"))\nmodel.eval()  # Set the model to evaluation mode\n\n### 4. Prepare the Handwritten Input Image\n#You need to preprocess the handwritten image to match the format of the MNIST dataset (28x28 pixels, grayscale).\ndef preprocess_image(image_path):\n    transform = transforms.Compose([\n        transforms.Grayscale(),  # Ensure the image is grayscale\n        transforms.Resize((28, 28)),  # Resize to 28x28 pixels\n        transforms.ToTensor(),  # Convert to tensor\n        transforms.Normalize((0.1307,), (0.3081,))  # Normalize with the same mean and std as MNIST\n    ])\n    image = Image.open(image_path)\n    image = transform(image).unsqueeze(0)  # Add batch dimension\n    return image\n\n### 5. Perform Inference\ndef recognize_digit(image_path):\n    image = preprocess_image(image_path)\n    with torch.no_grad():\n        output = model(image)\n        prediction = output.argmax(dim=1, keepdim=True)\n    return prediction.item()\n\n# Example usage\nimage_path = 'path_to_your_handwritten_digit_image3.png'\npredicted_digit = recognize_digit(image_path)\nprint(f'Predicted Digit: {predicted_digit}')\n\n```\n\n## calculator neural network\n\n```python\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport random\nimport numpy as np\n\n# Define the neural network architecture\nclass CalculatorNN(nn.Module):\n    def __init__(self):\n        super(CalculatorNN, self).__init__()\n        self.fc1 = nn.Linear(3, 128)  # Input: 2 numbers + operation\n        self.fc2 = nn.Linear(128, 64)\n        self.fc3 = nn.Linear(64, 1)   # Output: the result\n\n    def forward(self, x):\n        x = torch.relu(self.fc1(x))\n        x = torch.relu(self.fc2(x))\n        x = self.fc3(x)\n        return x\n\nmodel = CalculatorNN()\ncriterion = nn.MSELoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)\n\n# Training loop\nnum_epochs = 50000 # loss is too large if is 5000.\nfor epoch in range(num_epochs):\n    model.train()\n    # Forward pass\n    predictions = model(X_train)\n    loss = criterion(predictions, y_train)\n    # Backward pass and optimization\n    optimizer.zero_grad()\n    loss.backward()\n    optimizer.step()\n    if (epoch + 1) % 10 == 0:\n        print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')\n\n# ---- use\nmodel = CalculatorNN()\nmodel.load_state_dict(torch.load('calculator_model.pth'))\nmodel.eval()\n\n\n# Perform the prediction\nwith torch.no_grad():\n    # Prepare the input (32 * 3)\n    input_data = torch.tensor([[32.0, 3.0, 2]], dtype=torch.float32)  # 2 corresponds to multiplication\n    prediction = model(input_data)\n    print(f'Prediction for 32 * 3: {prediction.item():.4f}')\n\n```\n\n## Data cleaning\n* [log clean utils](./log_utils.py)\n```python\n## split by pattern, a full log for instance\ndef split_log_file(input_file, split_pattern, output_pattern):\n    with open(input_file, 'r') as file:\n        log_content = file.read()\n    pattern = re.compile(split_pattern)\n    split_points = [match.start() for match in re.finditer(pattern, log_content)]\n    split_points.append(len(log_content))\n    for i in range(len(split_points) - 1):\n        start = split_points[i]\n        end = split_points[i + 1]\n        segment = log_content[start:end]\n        match = pattern.search(segment)\n        if match:\n            number = match.group(1)\n            output_file = output_pattern.format(number=number)\n            with open(output_file, 'w') as file:\n                file.write(segment)\n            print(f\"Segment saved as {output_file}\")\n\n## difference patterns save log\ndef move_patterns_logs(destination_path, patterns):\n    current_directory = os.getcwd()\n    log_files = glob.glob(\"*.log\")\n    for log_file in log_files:\n        with open(log_file, 'r') as file:\n            if any(re.search(pattern, line) for pattern in patterns for line in file):\n                shutil.move(os.path.join(current_directory, log_file), destination_path)\n                break\n\n## filter show or data visualization\ndef filter_log_file(log_file_path, exclude_keywords):\n    with open(log_file_path, \"r\") as file:\n        lines = file.readlines()\n    filtered_lines = [line for line in lines if not any(keyword in line for keyword in exclude_keywords)]\n    for line in filtered_lines:\n        print(line, end=\"\")\n\n```\n\n## SVM\n![](svm_visualization_3d.gif)\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom mpl_toolkits.mplot3d import Axes3D\nfrom sklearn.datasets import make_classification\nfrom sklearn.svm import SVC\nfrom sklearn.preprocessing import StandardScaler\nfrom sklearn.model_selection import train_test_split\nX, y = make_classification(n_samples=100, n_features=3, n_informative=3, n_redundant=0, n_classes=2, random_state=42)\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)\nscaler = StandardScaler()\nX_train = scaler.fit_transform(X_train)\nX_test = scaler.transform(X_test)\nmodel = SVC(kernel='linear')\nmodel.fit(X_train, y_train)\ndef plot_svm_decision_boundary_3d(model, X, y):\n    fig = plt.figure(figsize=(10, 8))\n    ax = fig.add_subplot(111, projection='3d')\n    # Plot the training points\n    scatter = ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=y, s=30, cmap=plt.cm.coolwarm)\n    # Create grid to evaluate model (this defines the 3D space)\n    xlim = ax.get_xlim()\n    ylim = ax.get_ylim()\n    zlim = ax.get_zlim()\n    xx = np.linspace(xlim[0], xlim[1], 20)\n    yy = np.linspace(ylim[0], ylim[1], 20)\n    zz = np.linspace(zlim[0], zlim[1], 20)\n    # Create a meshgrid to evaluate the decision function\n    YY, ZZ = np.meshgrid(yy, zz)\n    XX = -(model.coef_[0][0] * YY + model.coef_[0][2] * ZZ + model.intercept_) / model.coef_[0][1]\n    # Plot the decision surface\n    ax.plot_surface(XX, YY, ZZ, color='gray', alpha=0.3, rstride=100, cstride=100)\n    # Highlight support vectors\n    ax.scatter(model.support_vectors_[:, 0], model.support_vectors_[:, 1], model.support_vectors_[:, 2],\n               s=100, facecolors='none', edgecolors='k', linewidth=1.5, label='Support Vectors')\n    ax.set_title('SVM Decision Boundary in 3D')\n    ax.set_xlabel('Feature 1')\n    ax.set_ylabel('Feature 2')\n    ax.set_zlabel('Feature 3')\n    # Add color legend\n    legend1 = ax.legend(*scatter.legend_elements(), loc=\"best\", title=\"Classes\")\n    ax.add_artist(legend1)\n    plt.show()\nplot_svm_decision_boundary_3d(model, X_train, y_train)\n```\n\n## kmeans\n* [kmeans log analysis](./kmeans_log_analysis.py)\n\n```python\nfrom sklearn.feature_extraction.text import TfidfVectorizer\nfrom sklearn.cluster import KMeans\n\ndef cluster_error_messages(error_messages, num_clusters=5):\n    vectorizer = TfidfVectorizer(stop_words='english')\n    X = vectorizer.fit_transform(error_messages)\n\n    kmeans = KMeans(n_clusters=num_clusters, random_state=0)\n    kmeans.fit(X)\n\n    labels = kmeans.labels_\n    clustered_errors = {}\n    for i, label in enumerate(labels):\n        if label not in clustered_errors:\n            clustered_errors[label] = []\n        clustered_errors[label].append(error_messages[i])\n    return clustered_errors\n```\n## Decision Tree Classifier\n\n\u003cimg src=\"DecisionTreeClassifier.png\" width=\"500\"\u003e\n\n```python\n\nimport matplotlib.pyplot as plt\nfrom sklearn.datasets import load_iris\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.tree import DecisionTreeClassifier, plot_tree\nfrom sklearn import metrics\niris = load_iris()\nX = iris.data  # Features\ny = iris.target  # Labels\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)\nclf = DecisionTreeClassifier()\nclf.fit(X_train, y_train)\ny_pred = clf.predict(X_test)\naccuracy = metrics.accuracy_score(y_test, y_pred)\nprint(f\"Accuracy: {accuracy * 100:.2f}%\")\nplt.figure(figsize=(12,8))\nplot_tree(clf, feature_names=iris.feature_names, class_names=iris.target_names, filled=True)\nplt.show()\n\n```\n\n## Reinforcement Learning (DQN)\n\n![](./rl_games/rl_gym_dqn_lunar.gif)\n\n\n```python\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nimport numpy as np\nimport random\n\n# Define a simple fully connected neural network\nclass DQN(nn.Module):\n    def __init__(self, input_dim, output_dim):\n        super(DQN, self).__init__()\n        self.fc1 = nn.Linear(input_dim, 128)\n        self.fc2 = nn.Linear(128, 128)\n        self.fc3 = nn.Linear(128, output_dim)\n\n    def forward(self, x):\n        x = F.relu(self.fc1(x))\n        x = F.relu(self.fc2(x))\n        return self.fc3(x)\n\n# ### 3. **Initialize the environment and model:**\n\nimport gymnasium as gym\nimport torch\n\nenv = gym.make(\"LunarLander-v2\", render_mode=\"human\")\nstate_dim = env.observation_space.shape[0]\naction_dim = env.action_space.n\n\n# Create the DQN model\nmodel = DQN(input_dim=state_dim, output_dim=action_dim)\n\n# ### 4. **Define the training loop:**\n# In this section, we'll define how the agent interacts with the environment, how rewards are collected, and how the model is updated.\n\n# Parameters\nlearning_rate = 0.001\ngamma = 0.99  # Discount factor\nepsilon = 1.0  # Exploration rate\nepsilon_decay = 0.995\nepsilon_min = 0.01\nepisodes = 500\n\n# Optimizer\noptimizer = optim.Adam(model.parameters(), lr=learning_rate)\n\n# Function to choose action (using epsilon-greedy policy)\ndef choose_action(state, epsilon):\n    if np.random.rand() \u003c= epsilon:\n        return np.random.choice(action_dim)  # Random action\n    state = torch.FloatTensor(state).unsqueeze(0)\n    with torch.no_grad():\n        q_values = model(state)\n    return torch.argmax(q_values).item()\n\n# Function to train the model\ndef train_model(memory, batch_size=64):\n    if len(memory) \u003c batch_size:\n        return\n\n    # Randomly sample a batch from memory\n    batch = random.sample(memory, batch_size)\n\n    # Extract states, actions, rewards, next_states, and dones from the batch\n    states, actions, rewards, next_states, dones = zip(*batch)\n\n    # Convert them to tensors\n    states = torch.FloatTensor(states)\n    actions = torch.LongTensor(actions)\n    rewards = torch.FloatTensor(rewards)\n    next_states = torch.FloatTensor(next_states)\n    dones = torch.FloatTensor(dones)\n\n    # Compute Q values for the current states\n    q_values = model(states).gather(1, actions.unsqueeze(1)).squeeze(1)\n\n    # Compute the maximum Q values for the next states\n    next_q_values = model(next_states).max(1)[0]\n\n    # Compute the target Q values\n    q_targets = rewards + (1 - dones) * gamma * next_q_values\n\n    # Compute the loss\n    loss = F.mse_loss(q_values, q_targets)\n\n    # Optimize the model\n    optimizer.zero_grad()\n    loss.backward()\n    optimizer.step()\n\n# Main loop\nmemory = []\n\nfor episode in range(episodes):\n    state = env.reset()[0]\n    total_reward = 0\n\n    for t in range(1000):\n        action = choose_action(state, epsilon)\n        next_state, reward, done, truncated, _ = env.step(action)\n        memory.append((state, action, reward, next_state, done))\n\n        train_model(memory)\n\n        state = next_state\n        total_reward += reward\n        if done or truncated:\n            break\n\n    epsilon = max(epsilon_min, epsilon * epsilon_decay)\n    print(f\"Episode {episode + 1}, Total Reward: {total_reward}\")\n\nenv.close()\n```\n\n## Flappy bird dqn\n\n![](./rl_games/flappy_bird_app/flappy_bird_torch_dqn_nocnn.gif)\n\n```python\nimport gymnasium as gym\nimport numpy as np\nimport pygame\nfrom gymnasium import spaces\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport random\nfrom collections import deque\nimport time\n\nimport pygame\nimport numpy as np\nfrom gymnasium import spaces\n\nfrom flappy_bird_cl3_pass_env_to_nn_3 import FlappyBirdEnv\n\nclass DQN(nn.Module):\n    def __init__(self, input_size, n_actions):\n        super(DQN, self).__init__()\n        self.fc = nn.Sequential(\n            nn.Linear(input_size, 64),\n            nn.ReLU(),\n            nn.Linear(64, 64),\n            nn.ReLU(),\n            nn.Linear(64, n_actions)\n        )\n\n    def forward(self, x):\n        return self.fc(x)\n\nclass DQNAgent:\n    def __init__(self, env, learning_rate=1e-3, gamma=0.99, epsilon_start=1.0, epsilon_final=0.01, epsilon_decay=0.995):\n        self.env = env\n        self.n_actions = env.action_space.n\n        self.device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n        self.epsilon = epsilon_start\n        self.epsilon_final = epsilon_final\n        self.epsilon_decay = epsilon_decay\n\n        self.memory = deque(maxlen=10000)\n        self.batch_size = 64\n\n        state_size = len(env.get_state())\n        self.model = DQN(state_size, self.n_actions).to(self.device)\n        self.optimizer = optim.Adam(self.model.parameters(), lr=learning_rate)\n        self.criterion = nn.MSELoss()\n\n        self.gamma = gamma\n\n    def get_action(self, state):\n        if random.random() \u003c self.epsilon:\n            return random.randint(0, self.n_actions - 1)\n\n        with torch.no_grad():\n            state = torch.FloatTensor(state).unsqueeze(0).to(self.device)\n            q_values = self.model(state)\n            return torch.argmax(q_values).item()\n\n    def update_epsilon(self):\n        self.epsilon = max(self.epsilon_final, self.epsilon * self.epsilon_decay)\n\n    def remember(self, state, action, reward, next_state, done):\n        self.memory.append((state, action, reward, next_state, done))\n\n    def train(self):\n        if len(self.memory) \u003c self.batch_size:\n            return\n\n        batch = random.sample(self.memory, self.batch_size)\n        states, actions, rewards, next_states, dones = zip(*batch)\n\n        states = torch.FloatTensor(states).to(self.device)\n        actions = torch.LongTensor(actions).to(self.device)\n        rewards = torch.FloatTensor(rewards).to(self.device)\n        next_states = torch.FloatTensor(next_states).to(self.device)\n        dones = torch.FloatTensor(dones).to(self.device)\n\n        current_q_values = self.model(states).gather(1, actions.unsqueeze(1))\n        with torch.no_grad():\n            next_q_values = self.model(next_states).max(1)[0]\n        target_q_values = rewards + (1 - dones) * self.gamma * next_q_values\n\n        loss = self.criterion(current_q_values.squeeze(), target_q_values)\n\n        self.optimizer.zero_grad()\n        loss.backward()\n        self.optimizer.step()\n\ndef train_dqn(env, episodes=2000, max_steps=1000, render_interval=10):\n    agent = DQNAgent(env)\n    scores = []\n\n    for episode in range(episodes):\n        state = env.reset()\n        score = 0\n\n        for step in range(max_steps):\n            if episode % render_interval == 0:\n                env.render()\n\n            action = agent.get_action(state)\n            next_state, reward, done, _, _ = env.step(action)\n            agent.remember(state, action, reward, next_state, done)\n            agent.train()\n\n            state = next_state\n            score += reward\n\n            if done:\n                break\n\n            if episode % render_interval == 0:\n                pygame.event.pump()\n\n        agent.update_epsilon()\n        scores.append(score)\n\n        if episode % 10 == 0:\n            print(f\"Episode: {episode}, Score: {score}, Epsilon: {agent.epsilon:.2f}\")\n\n    return agent, scores\n\nif __name__ == \"__main__\":\n    env = FlappyBirdEnv()\n    agent, scores = train_dqn(env, episodes=6000, render_interval=50)\n\n    # Test the trained agent\n    state = env.reset()\n    done = False\n    score = 0\n\n    while not done:\n        env.render()\n        action = agent.get_action(state)\n        next_state, reward, done, _, _ = env.step(action)\n        state = next_state\n        score += reward\n\n        for event in pygame.event.get():\n            if event.type == pygame.QUIT:\n                done = True\n\n        pygame.event.pump()\n        time.sleep(0.03)\n\n    print(f\"Final Score: {score}\")\n    env.close()\n```\n\n## SGD\n![](./deep_learning_basic_funcs/sgd_visualization_animation.gif)\n\n```python\nimport torch\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom mpl_toolkits.mplot3d import Axes3D\nfrom matplotlib.animation import FuncAnimation\n\n# Random 3D surface (loss function)\ndef loss_function(x, y):\n    return torch.sin(x) * torch.cos(y) + 0.1 * (x**2 + y**2)\n\n# Generate a meshgrid for plotting the surface\nx = torch.linspace(-5, 5, 100)\ny = torch.linspace(-5, 5, 100)\nX, Y = torch.meshgrid(x, y)\nZ = loss_function(X, Y).detach().numpy()\n\n# Initialize figure and 3D axis for animation\nfig = plt.figure(figsize=(10, 7))\nax = fig.add_subplot(111, projection='3d')\nax.set_xlabel('X')\nax.set_ylabel('Y')\nax.set_zlabel('Z')\nax.set_title('SGD Optimization Path on 3D Surface')\n\n# Plot the static 3D surface\nax.plot_surface(X.numpy(), Y.numpy(), Z, cmap='viridis', alpha=0.7)\n\n# SGD starting point\nstart_point = torch.tensor([4.0, 4.0], requires_grad=True)\n\n# Hyperparameters\nlearning_rate = 0.1\noptimizer = torch.optim.SGD([start_point], lr=learning_rate)\n\n# Number of steps and animation frames\nsteps = 10\npath = np.zeros((steps, 3))\n\n# Plotting the initial point on the surface\npoint_plot, = ax.plot([], [], [], color='r', marker='o', markersize=5)\n\n# Function to update the frame during animation\ndef update(i):\n    global start_point\n\n    optimizer.zero_grad()\n\n    # Calculate the loss (z value)\n    loss = loss_function(start_point[0], start_point[1])\n\n    # Backpropagation to compute gradients\n    loss.backward()\n\n    # Perform optimization step\n    optimizer.step()\n\n    # Store the (x, y, z) values\n    path[i, 0] = start_point[0].item()\n    path[i, 1] = start_point[1].item()\n    path[i, 2] = loss.item()\n\n    # Update point on the surface\n    point_plot.set_data(path[:i+1, 0], path[:i+1, 1])\n    point_plot.set_3d_properties(path[:i+1, 2])\n    \n    return point_plot,\n\n# Animate SGD for 10 steps\nani = FuncAnimation(fig, update, frames=steps, interval=500, blit=True)\n\n# Show the animation\nplt.show()\n\n```\n\n## CNN with Attention\n\n```python\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nclass Attention(nn.Module):\n    def __init__(self, in_channels, out_channels):\n        super(Attention, self).__init__()\n        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1)\n        self.softmax = nn.Softmax(dim=-1)\n\n    def forward(self, x):\n        # Global feature extraction\n        global_features = torch.mean(x, dim=(2, 3), keepdim=True)\n        attention_map = self.conv(global_features)\n        attention_map = self.softmax(attention_map)\n        out = x * attention_map\n        return out\n\nclass CNNWithAttention(nn.Module):\n    def __init__(self):\n        super(CNNWithAttention, self).__init__()\n        # Convolutional layers\n        self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)\n        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)\n        self.pool = nn.MaxPool2d(2, 2)\n\n        # Attention layer\n        self.attention = Attention(64, 64)\n\n        # Fully connected layers\n        self.fc1 = nn.Linear(64 * 8 * 8, 512)\n        self.fc2 = nn.Linear(512, 10)\n\n    def forward(self, x):\n        x = self.pool(F.relu(self.conv1(x)))\n        x = self.pool(F.relu(self.conv2(x)))\n\n        # Attention mechanism\n        x = self.attention(x)\n\n        x = x.view(-1, 64 * 8 * 8)\n        x = F.relu(self.fc1(x))\n        x = self.fc2(x)\n        return x\n\n# --\n# Initialize the model, loss function, and optimizer\nmodel = CNNWithAttention()\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)\n\n# Training loop\nfor epoch in range(5):  # Train for 5 epochs\n    running_loss = 0.0\n    for inputs, labels in trainloader:\n        # Zero the parameter gradients\n        optimizer.zero_grad()\n\n        # Forward pass\n        outputs = model(inputs)\n        loss = criterion(outputs, labels)\n\n        # Backward pass and optimize\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item()\n\n    print(f\"Epoch [{epoch + 1}/5], Loss: {running_loss / len(trainloader)}\")\n\n```\n\n## LSTM generator\n\n```python\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\n\n\nclass Vocab:\n    def __init__(self, stoi, itos):\n        self.stoi = stoi\n        self.itos = itos\n\n# Provided corpus (AI history)\ncorpus = \"\"\"\nThe history of artificial intelligence (AI) began in antiquity, with myths, stories and rumors of artificial beings endowed with intelligence or consciousness by master craftsmen.\n... ...\n\"\"\"\n\n# Simple tokenization (splitting by spaces)\ncorpus = corpus.replace(\"\\n\", \" \")  # Remove newlines\n\n# Tokenization can be improved using libraries like nltk or spacy, but we'll use a simple split here\ntokens = corpus.split()\n\n# You can build a vocabulary from this corpus as you did before, for instance:\nfrom collections import Counter\n\n# Create a vocabulary from the corpus\ntoken_counts = Counter(tokens)\nvocab_stoi = {token: idx for idx, (token, count) in enumerate(token_counts.items())}\nvocab_itos = {idx: token for token, idx in vocab_stoi.items()}\n\n# Create the Vocab object\nvocab = Vocab(stoi=vocab_stoi, itos=vocab_itos)\n\nclass RNNModel(nn.Module):\n    def __init__(self, vocab_size, embed_size, hidden_size, num_layers):\n        super(RNNModel, self).__init__()\n        self.num_layers = num_layers\n        self.hidden_size = hidden_size\n        self.embedding = nn.Embedding(vocab_size, embed_size)\n        self.rnn = nn.LSTM(embed_size, hidden_size, num_layers, batch_first=True)\n        self.fc = nn.Linear(hidden_size, vocab_size)\n\n    def forward(self, x, hidden):\n        x = self.embedding(x)\n        out, hidden = self.rnn(x, hidden)\n        out = self.fc(out)\n        return out, hidden\n\n    def init_hidden(self, batch_size):\n        # Initialize hidden states (h_0) and cell states (c_0) with correct batch size\n        weight = next(self.parameters()).data\n        return (weight.new_zeros(self.num_layers, batch_size, self.hidden_size),\n                weight.new_zeros(self.num_layers, batch_size, self.hidden_size))\n\nclass TextDataset(Dataset):\n    def __init__(self, text, vocab, sequence_length):\n        self.vocab = vocab\n        self.sequence_length = sequence_length\n        self.data = self.tokenize_and_encode(text)\n    def tokenize_and_encode(self, text):\n        tokens = text.split()  # Simple tokenization (split by spaces)\n        return [self.vocab.stoi[token] for token in tokens if token in self.vocab.stoi]\n    def __len__(self):\n        return len(self.data) - self.sequence_length\n    def __getitem__(self, idx):\n        x = self.data[idx:idx + self.sequence_length]\n        y = self.data[idx + 1:idx + 1 + self.sequence_length]\n        return torch.tensor(x, dtype=torch.long), torch.tensor(y, dtype=torch.long)\n\n# Define sequence length and batch size\nsequence_length = 10  # Can be tuned\nbatch_size = 100\n\n# Create the dataset and dataloader\ndataset = TextDataset(corpus, vocab, sequence_length)\ntrain_loader = DataLoader(dataset, batch_size=batch_size, shuffle=True)\n\n# Now you're ready to train the model using the provided corpus\n\n# Define model, loss function, and optimizer\nvocab_size = len(vocab.stoi)\nembed_size = 50  # Adjust as needed\nhidden_size = 100  # Adjust as needed\nnum_layers = 2\nnum_epochs = 100  # Adjust based on performance\nlearning_rate = 0.001\n\nmodel = RNNModel(vocab_size, embed_size, hidden_size, num_layers)\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=learning_rate)\n\n# Training loop\nfor epoch in range(num_epochs):\n    for batch in train_loader:\n        inputs, targets = batch\n        batch_size = inputs.size(0)  # Get the actual batch size for this iteration\n        hidden = model.init_hidden(batch_size)  # Initialize hidden state with correct batch size\n\n        outputs, hidden = model(inputs, hidden)\n        loss = criterion(outputs.view(-1, vocab_size), targets.view(-1))\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n    print(f'Epoch {epoch+1}, Loss: {loss.item()}')\n\ntorch.save(model.state_dict(), 'rnn_model_ai.pth')\ndef generate_text(model, start_text, max_length=100):\n    model.eval()\n    hidden = model.init_hidden(1)  # Start with batch size 1\n    input = torch.tensor([[vocab.stoi[start_text]]])  # Convert start_text to input tensor\n    result = [start_text]\n    for _ in range(max_length):\n        output, hidden = model(input, hidden)\n        prob = nn.functional.softmax(output[0, -1], dim=0).data\n        next_word = torch.multinomial(prob, 1).item()\n        result.append(vocab.itos[next_word])  # Convert back to word using vocab\n        input = torch.tensor([[next_word]])  # Feed the next word as input\n    return ' '.join(result)\nstart_text = 'AI'  # The starting word\ngenerated_text = generate_text(model, start_text, max_length=100)\nprint(generated_text)\n\n```\n\n## Seq2seq number translator\n\n```python\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport numpy as np\nimport random\nimport matplotlib.pyplot as plt\n\nimport random\n\nclass NumeralTranslationDataset:\n    def __init__(self):\n        # Comprehensive mapping of Arabic numerals to English words\n        self.num_to_words = {\n            '0': 'zero', '1': 'one', '2': 'two', '3': 'three', '4': 'four', \n            '5': 'five', '6': 'six', '7': 'seven', '8': 'eight', '9': 'nine',\n            '10': 'ten', '11': 'eleven', '12': 'twelve', '13': 'thirteen', \n            '14': 'fourteen', '15': 'fifteen', '16': 'sixteen', \n            '17': 'seventeen', '18': 'eighteen', '19': 'nineteen',\n            '20': 'twenty', '21': 'twenty one', '22': 'twenty two', \n            '23': 'twenty three', '24': 'twenty four', '25': 'twenty five',\n            '30': 'thirty', '31': 'thirty one', '32': 'thirty two', \n            '33': 'thirty three', '34': 'thirty four', '35': 'thirty five',\n            '40': 'forty', '41': 'forty one', '42': 'forty two', \n            '43': 'forty three', '44': 'forty four', '45': 'forty five',\n            '50': 'fifty', '51': 'fifty one', '52': 'fifty two', \n            '53': 'fifty three', '54': 'fifty four', '55': 'fifty five',\n            '60': 'sixty', '61': 'sixty one', '62': 'sixty two', \n            '63': 'sixty three', '64': 'sixty four', '65': 'sixty five',\n            '70': 'seventy', '71': 'seventy one', '72': 'seventy two', \n            '73': 'seventy three', '74': 'seventy four', '75': 'seventy five',\n            '80': 'eighty', '81': 'eighty one', '82': 'eighty two', \n            '83': 'eighty three', '84': 'eighty four', '85': 'eighty five',\n            '90': 'ninety', '91': 'ninety one', '92': 'ninety two', \n            '93': 'ninety three', '94': 'ninety four', '95': 'ninety five'\n        }\n\n    def generate_training_data(self, num_examples=1000):\n        \"\"\"Generate random training data for number translation.\"\"\"\n        input_sequences = []\n        target_sequences = []\n\n        # Generate random numbers from 0 to 99 for a total of `num_examples` examples\n        for _ in range(num_examples):\n            num = random.randint(0, 99)  # Randomly pick a number from 0 to 99\n            num_str = str(num)\n            \n            # Translate to words\n            if num in self.num_to_words:\n                word = self.num_to_words[num_str]\n            elif num \u003c 20:\n                # Handle teens\n                units = str(num % 10)\n                word = self.num_to_words[units]\n            else:\n                # Handle 21-99\n                tens = str((num // 10) * 10)\n                units = str(num % 10)\n                tens_word = self.num_to_words[tens]\n                units_word = self.num_to_words[units] if units != '0' else ''\n                word = f\"{tens_word} {units_word}\".strip()\n            \n            input_sequences.append(list(num_str))\n            target_sequences.append(list(word))\n\n        return input_sequences, target_sequences\n\nclass Encoder(nn.Module):\n    def __init__(self, input_size, embedding_dim, hidden_dim):\n        super(Encoder, self).__init__()\n        self.embedding = nn.Embedding(input_size, embedding_dim)\n        self.gru = nn.GRU(embedding_dim, hidden_dim, batch_first=True, num_layers=2, dropout=0.2)\n        \n    def forward(self, x):\n        embedded = self.embedding(x)\n        outputs, hidden = self.gru(embedded)\n        return outputs, hidden\n\nclass Attention(nn.Module):\n    def __init__(self, hidden_dim):\n        super(Attention, self).__init__()\n        self.attn = nn.Linear(hidden_dim * 2, hidden_dim)\n        self.v = nn.Parameter(torch.rand(hidden_dim))\n        \n    def forward(self, hidden, encoder_outputs):\n        # hidden = [batch size, hidden dim]\n        # encoder_outputs = [batch size, seq len, hidden dim]\n        \n        batch_size = encoder_outputs.shape[0]\n        src_len = encoder_outputs.shape[1]\n        \n        # Repeat hidden state src_len times\n        hidden = hidden.unsqueeze(1).repeat(1, src_len, 1)\n        \n        # Concatenate hidden state with encoder outputs\n        energy = torch.tanh(self.attn(torch.cat((hidden, encoder_outputs), dim=-1)))\n        \n        # Compute attention scores\n        attention = torch.sum(self.v * energy, dim=-1)\n        \n        return torch.softmax(attention, dim=1)\n\nclass Decoder(nn.Module):\n    def __init__(self, output_size, embedding_dim, hidden_dim):\n        super(Decoder, self).__init__()\n        self.embedding = nn.Embedding(output_size, embedding_dim)\n        self.attention = Attention(hidden_dim)\n        self.gru = nn.GRU(embedding_dim + hidden_dim, hidden_dim, batch_first=True, num_layers=2, dropout=0.2)\n        self.fc_out = nn.Linear(hidden_dim, output_size)\n        \n    def forward(self, input, hidden, encoder_outputs):\n        # input = [batch size, 1]\n        # hidden = [batch size, hidden dim]\n        # encoder_outputs = [batch size, src len, hidden dim]\n        \n        # Embedding input\n        embedded = self.embedding(input)\n        \n        # Compute attention weights\n        a = self.attention(hidden[-1], encoder_outputs)\n        \n        # Apply attention to encoder outputs\n        attended = torch.bmm(a.unsqueeze(1), encoder_outputs).squeeze(1)\n        \n        # Concatenate embedded input with attended context\n        rnn_input = torch.cat((embedded.squeeze(1), attended), dim=1).unsqueeze(1)\n        \n        # GRU step\n        output, hidden = self.gru(rnn_input, hidden)\n        \n        # Prediction\n        prediction = self.fc_out(output.squeeze(1))\n        \n        return prediction, hidden, a\n\nclass Seq2SeqTranslator(nn.Module):\n    def __init__(self, input_size, output_size, embedding_dim, hidden_dim):\n        super(Seq2SeqTranslator, self).__init__()\n        self.encoder = Encoder(input_size, embedding_dim, hidden_dim)\n        self.decoder = Decoder(output_size, embedding_dim, hidden_dim)\n        \n    def forward(self, input_seq, target_seq, teacher_forcing_ratio=0.5):\n        batch_size = input_seq.size(0)\n        target_len = target_seq.size(1)\n        target_vocab_size = self.decoder.fc_out.out_features\n        \n        # Tensor to store decoder outputs\n        outputs = torch.zeros(batch_size, target_len, target_vocab_size)\n        \n        # Encoder\n        encoder_outputs, hidden = self.encoder(input_seq)\n        \n        # First decoder input\n        decoder_input = torch.zeros(batch_size, 1, dtype=torch.long)\n        \n        # Decode\n        for t in range(target_len):\n            decoder_output, hidden, _ = self.decoder(decoder_input, hidden, encoder_outputs)\n            outputs[:, t:t+1, :] = decoder_output.unsqueeze(1)\n            \n            # Teacher forcing\n            teacher_force = random.random() \u003c teacher_forcing_ratio\n            top1 = decoder_output.argmax(1)\n            \n            if teacher_force:\n                decoder_input = target_seq[:, t:t+1]\n            else:\n                decoder_input = top1.unsqueeze(1)\n        \n        return outputs\n\nclass NumeralTranslator:\n    def __init__(self, input_chars, output_chars):\n        # Create dataset\n        self.dataset = NumeralTranslationDataset()\n        \n        # Create character to index mappings\n        self.input_char_to_idx = {char: i for i, char in enumerate(input_chars)}\n        self.input_idx_to_char = {i: char for char, i in self.input_char_to_idx.items()}\n        \n        self.output_char_to_idx = {char: i for i, char in enumerate(output_chars)}\n        self.output_idx_to_char = {i: char for char, i in self.output_char_to_idx.items()}\n        \n        # Hyperparameters\n        self.embedding_dim = 128\n        self.hidden_dim = 256\n        \n        # Initialize model\n        self.model = Seq2SeqTranslator(\n            input_size=len(input_chars),\n            output_size=len(output_chars),\n            embedding_dim=self.embedding_dim,\n            hidden_dim=self.hidden_dim\n        )\n        \n        self.criterion = nn.CrossEntropyLoss()\n        self.optimizer = optim.Adam(self.model.parameters(), lr=0.001)\n    \n    def prepare_sequence(self, seq, char_to_idx):\n        \"\"\"Convert sequence of characters to tensor of indices.\"\"\"\n        return torch.tensor([char_to_idx.get(char, 0) for char in seq], dtype=torch.long)\n    \n    def pad_sequences(self, sequences, pad_token):\n        \"\"\"Pad sequences to equal length.\"\"\"\n        # Convert sequences to lists if they are tensors\n        sequences = [seq.tolist() if torch.is_tensor(seq) else seq for seq in sequences]\n        \n        max_len = max(len(seq) for seq in sequences)\n        padded = []\n        for seq in sequences:\n            padded.append(seq + [pad_token] * (max_len - len(seq)))\n        return torch.tensor(padded, dtype=torch.long)\n    \n    def train(self, epochs=300, batch_size=32):\n        \"\"\"Train the translation model.\"\"\"\n        # Generate training data\n        input_sequences, target_sequences = self.dataset.generate_training_data()\n        \n        # Prepare input and target sequences\n        input_chars = [list(str(seq)) for seq in input_sequences]\n        target_chars = [list(seq) for seq in target_sequences]\n        \n        # Get character sets for input and output\n        input_chars_set = sorted(set(''.join([''.join(seq) for seq in input_chars])))\n        output_chars_set = sorted(set(''.join([''.join(seq) for seq in target_chars])))\n        \n        print(\"Input characters:\", input_chars_set)\n        print(\"Output characters:\", output_chars_set)\n        \n        # Training loop\n        epoch_losses = []\n        for epoch in range(epochs):\n            total_loss = 0\n            \n            # Shuffle data\n            combined = list(zip(input_chars, target_chars))\n            random.shuffle(combined)\n            input_chars, target_chars = zip(*combined)\n            \n            for i in range(0, len(input_chars), batch_size):\n                batch_input = input_chars[i:i+batch_size]\n                batch_target = target_chars[i:i+batch_size]\n                \n                # Prepare input sequences\n                input_seqs = self.pad_sequences(\n                    [self.prepare_sequence(seq, self.input_char_to_idx) for seq in batch_input], \n                    pad_token=0\n                )\n                \n                # Prepare target sequences\n                target_seqs = self.pad_sequences(\n                    [self.prepare_sequence(seq, self.output_char_to_idx) for seq in batch_target], \n                    pad_token=0\n                )\n                \n                # Zero gradients\n                self.optimizer.zero_grad()\n                \n                # Forward pass\n                outputs = self.model(input_seqs, target_seqs)\n                \n                # Compute loss\n                loss = self.criterion(\n                    outputs.view(-1, outputs.size(-1)), \n                    target_seqs.view(-1)\n                )\n                \n                # Backward pass\n                loss.backward()\n                self.optimizer.step()\n                \n                total_loss += loss.item()\n            \n            # Record average epoch loss\n            avg_loss = total_loss / (len(input_chars) // batch_size)\n            epoch_losses.append(avg_loss)\n            \n            # Print progress\n            if epoch % 10 == 0:\n                print(f'Epoch {epoch}, Loss: {avg_loss:.4f}')\n        \n        # Visualize training loss\n        self.plot_training_loss(epoch_losses)\n        \n        return epoch_losses\n    \n    def translate(self, input_number):\n        \"\"\"Translate a single number to words.\"\"\"\n        # Prepare input sequence\n        input_seq = self.prepare_sequence(list(str(input_number)), self.input_char_to_idx)\n        input_seq = input_seq.unsqueeze(0)  # Add batch dimension\n        \n        # Create dummy target sequence of zeros\n        max_output_length = 10  # Maximum expected word length\n        dummy_target = torch.zeros(1, max_output_length, dtype=torch.long)\n        \n        # Disable gradient computation\n        with torch.no_grad():\n            # Get model outputs\n            outputs = self.model(input_seq, dummy_target)\n            \n            # Get the most likely output characters\n            predicted_indices = outputs.argmax(dim=-1)\n            \n            # Convert indices back to characters\n            predicted_chars = []\n            for i in range(predicted_indices.size(1)):\n                char_idx = predicted_indices[0, i].item()\n                char = self.output_idx_to_char[char_idx]\n                if char != '\u003cpxad\u003e':  # Skip padding\n                    predicted_chars.append(char)\n            \n            # Join characters to form a word\n            return ''.join(predicted_chars).strip()\n    \n    def save_model(self, filepath='numeral_translator.pth'):\n        \"\"\"Save model state.\"\"\"\n        torch.save({\n            'model_state_dict': self.model.state_dict(),\n            'input_char_to_idx': self.input_char_to_idx,\n            'output_char_to_idx': self.output_char_to_idx\n        }, filepath)\n        print(f\"Model saved to {filepath}\")\n    \n    def load_model(self, filepath='numeral_translator.pth'):\n        \"\"\"Load model state.\"\"\"\n        checkpoint = torch.load(filepath)\n        self.model.load_state_dict(checkpoint['model_state_dict'])\n        self.input_char_to_idx = checkpoint['input_char_to_idx']\n        self.output_char_to_idx = checkpoint['output_char_to_idx']\n        print(f\"Model loaded from {filepath}\")\n    \n    def plot_training_loss(self, losses):\n        \"\"\"Visualize training loss.\"\"\"\n        plt.figure(figsize=(10, 5))\n        plt.plot(losses, label='Training Loss')\n        plt.title('Training Loss Over Epochs')\n        plt.xlabel('Epoch')\n        plt.ylabel('Loss')\n        plt.legend()\n        plt.tight_layout()\n        plt.savefig('training_loss.png')\n        plt.close()\n\ndef main():\n    # Define input and output character sets\n    input_chars = list('0123456789')\n    output_chars = list(' abcdefghijklmnopqrstuvwxyz') + ['\u003cpad\u003e']\n\n    # Initialize translator\n    translator = NumeralTranslator(input_chars, output_chars)\n\n    # Train the model\n    print(\"Training model...\")\n    losses = translator.train(epochs=300, batch_size=32)\n\n    # Save the trained model\n    translator.save_model()\n\n    # Test the model with some examples\n    test_numbers = ['0', '5', '13', '25', '42', '67', '89', '99']\n    print(\"\\nTesting translations:\")\n    for number in test_numbers:\n        translation = translator.translate(number)\n        print(f\"{number} -\u003e {translation}\")\n\n    # Interactive mode\n    print(\"\\nEnter a number (0-99) to translate or 'q' to quit:\")\n    while True:\n        user_input = input(\"\u003e \")\n        if user_input.lower() == 'q':\n            break\n        try:\n            number = int(user_input)\n            if 0 \u003c= number \u003c= 99:\n                translation = translator.translate(user_input)\n                print(f\"Translation: {translation}\")\n            else:\n                print(\"Please enter a number between 0 and 99\")\n        except ValueError:\n            print(\"Invalid input. Please enter a valid number or 'q' to quit\")\n\nif __name__ == \"__main__\":\n    main()\n```\n\n## Transformer generator\n\n```python\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\nimport math\nclass Vocab:\n    def __init__(self, stoi, itos):\n        self.stoi = stoi\n        self.itos = itos\n\ncorpus = \"\"\"\nThe history of artificial intelligence (AI) began in antiquity, with myths, stories and rumors of artificial beings endowed with intelligence or consciousness by master craftsmen.\n...\n\"\"\"\ncorpus = corpus.replace(\"\\n\", \" \")\ntokens = corpus.split()\nfrom collections import Counter\ntoken_counts = Counter(tokens)\nvocab_stoi = {token: idx for idx, (token, count) in enumerate(token_counts.items())}\nvocab_itos = {idx: token for token, idx in vocab_stoi.items()}\nvocab = Vocab(stoi=vocab_stoi, itos=vocab_itos)\n\nclass PositionalEncoding(nn.Module):\n    def __init__(self, embed_size, max_len=5000):\n        super(PositionalEncoding, self).__init__()\n        self.encoding = torch.zeros(max_len, embed_size)\n        position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)\n        div_term = torch.exp(torch.arange(0, embed_size, 2).float() * (-math.log(10000.0) / embed_size))\n        self.encoding[:, 0::2] = torch.sin(position * div_term)\n        self.encoding[:, 1::2] = torch.cos(position * div_term)\n        self.encoding = self.encoding.unsqueeze(0)\n    def forward(self, x):\n        return x + self.encoding[:, :x.size(1), :].to(x.device)\n\nclass TransformerModel(nn.Module):\n    def __init__(self, vocab_size, embed_size, num_heads, hidden_size, num_layers, dropout=0.1):\n        super(TransformerModel, self).__init__()\n        self.embedding = nn.Embedding(vocab_size, embed_size)\n        self.pos_encoder = PositionalEncoding(embed_size)\n        encoder_layers = nn.TransformerEncoderLayer(embed_size, num_heads, hidden_size, dropout)\n        self.transformer = nn.TransformerEncoder(encoder_layers, num_layers)\n        self.fc = nn.Linear(embed_size, vocab_size)\n    def forward(self, src, src_mask=None):\n        src = self.embedding(src) * math.sqrt(src.size(-1))  # scale by sqrt(embed_size)\n        src = self.pos_encoder(src)\n        output = self.transformer(src, src_mask)\n        output = self.fc(output)\n        return output\n\nclass TextDataset(Dataset):\n    def __init__(self, text, vocab, sequence_length):\n        self.vocab = vocab\n        self.sequence_length = sequence_length\n        self.data = self.tokenize_and_encode(text)\n    def tokenize_and_encode(self, text):\n        tokens = text.split()\n        return [self.vocab.stoi[token] for token in tokens if token in self.vocab.stoi]\n    def __len__(self):\n        return len(self.data) - self.sequence_length\n    def __getitem__(self, idx):\n        x = self.data[idx:idx + self.sequence_length]\n        y = self.data[idx + 1:idx + 1 + self.sequence_length]\n        return torch.tensor(x, dtype=torch.long), torch.tensor(y, dtype=torch.long)\n\nsequence_length = 10\nbatch_size = 100\ndataset = TextDataset(corpus, vocab, sequence_length)\ntrain_loader = DataLoader(dataset, batch_size=batch_size, shuffle=True)\nvocab_size = len(vocab.stoi)\nembed_size = 50  # Can be tuned\nnum_heads = 2  # Number of attention heads\nhidden_size = 100  # Hidden layer size in feedforward network\nnum_layers = 88  # Number of Transformer layers\ndropout = 0.1\nnum_epochs = 100  # Adjust based on performance\nlearning_rate = 0.001\nmodel = TransformerModel(vocab_size, embed_size, num_heads, hidden_size, num_layers, dropout)\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=learning_rate)\n\nfor epoch in range(num_epochs):\n    for batch in train_loader:\n        inputs, targets = batch\n        inputs = inputs.permute(1, 0)  # (batch_size, sequence_length) -\u003e (sequence_length, batch_size)\n        targets = targets.permute(1, 0)\n        outputs = model(inputs)\n\n        # Instead of view(), use reshape()\n        loss = criterion(outputs.reshape(-1, vocab_size), targets.reshape(-1))\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n    print(f'Epoch {epoch+1}, Loss: {loss.item()}')\n\ntorch.save(model.state_dict(), 'transformer_model_ai.pth')\n\ndef generate_text(model, start_text, max_length=100):\n    model.eval()\n    input = torch.tensor([[vocab.stoi[start_text]]]).permute(1, 0)  # Convert start_text to input tensor\n    result = [start_text]\n    for _ in range(max_length):\n        output = model(input)\n        prob = nn.functional.softmax(output[-1, 0], dim=0).data\n        next_word = torch.multinomial(prob, 1).item()\n        result.append(vocab.itos[next_word])\n        input = torch.cat([input, torch.tensor([[next_word]])], dim=0)\n    return ' '.join(result)\nstart_text = 'AI'\ngenerated_text = generate_text(model, start_text, max_length=100)\nprint(generated_text)\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxlisp%2Fvisualization-machine-learning","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxlisp%2Fvisualization-machine-learning","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxlisp%2Fvisualization-machine-learning/lists"}