Why consider Go for ML at all?
Python is a great language for prototyping and research, but it has its limitations:
Performance: Python is slow, especially without optimized libraries
Parallelism: GIL (Global Interpreter Lock) complicates multithreading
Deployment: packaging Python applications with dependencies is a tough task
Typification: dynamic typing can lead to errors in production
Go solves many of these problems:
High-performance compiled language
Built-in support for competitiveness through hotlines
One binary file without dependencies
Static typing
What can you do on Go in the ML area?
1. Inference (application of ready-made models)
The most popular scenario is the use of already trained models. You train the model in Python and then use it in production on Go.
Example with ONNX Runtime:
package main
import (
"fmt"
onnxruntime "github.com/yalue/onnxruntime_go"
)
func main() {
// Loading the model trained in PyTorch/TensorFlow
session, err := onnxruntime.NewSession[float32](
"model.onnx",
[]string{"input"},
[]string{"output"},
nil,
)
if err != nil {
panic(err)
}
defer session.Destroy()
// Preparing input data
input := []float32{1.0, 2.0, 3.0, 4.0}
// Making a prediction
output, err := session.Run([][]float32{input})
if err != nil {
panic(err)
}
fmt.Println("Prediction:", output[0])
}2. Classic ML algorithms
Many tasks do not require neural networks. Linear regression, decision trees, k-means — all this can be implemented in Go.
GoLearn Library:
package main
import (
"fmt"
"github.com/sjwhitworth/golearn/base"
"github.com/sjwhitworth/golearn/evaluation"
"github.com/sjwhitworth/golearn/knn"
)
func main() {
// Loading data
rawData, err := base.ParseCSVToInstances("data.csv", true)
if err != nil {
panic(err)
}
// Creating a KNN classifier
cls := knn.NewKnnClassifier("euclidean", "linear", 2)
// We divide into train/test
trainData, testData := base.InstancesTrainTestSplit(rawData, 0.7)
// We train
cls.Fit(trainData)
// Checking the accuracy
predictions, err := cls.Predict(testData)
if err != nil {
panic(err)
}
confusionMat, err := evaluation.GetConfusionMatrix(testData, predictions)
if err != nil {
panic(err)
}
fmt.Println(evaluation.GetAccuracy(confusionMat))
}3. Data processing and feature engineering
Go is great for ETL pipelines and processing large amounts of data.
package main
import (
"encoding/csv"
"os"
"strconv"
"sync"
)
type DataPoint struct {
Feature1 float64
Feature2 float64
Label int
}
func processData(filename string) ([]DataPoint, error) {
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
reader := csv.NewReader(file)
records, err := reader.ReadAll()
if err != nil {
return nil, err
}
// Parallel processing through the cores
var wg sync.WaitGroup
results := make([]DataPoint, len(records)-1)
for i, record := range records[1:] {
wg.Add(1)
go func(idx int, rec []string) {
defer wg.Done()
f1, _ := strconv.ParseFloat(rec[0], 64)
f2, _ := strconv.ParseFloat(rec[1], 64)
label, _ := strconv.Atoi(rec[2])
// Normalization or other transformations
results[idx] = DataPoint{
Feature1: (f1 - 50) / 10,
Feature2: (f2 - 100) / 20,
Label: label,
}
}(i, record)
}
wg.Wait()
return results, nil
}4. Microservices for ML
Go is ideal for creating APIs that serve ML models:
package main
import (
"encoding/json"
"net/http"
"log"
)
type PredictionRequest struct {
Features []float64 `json:"features"`
}
type PredictionResponse struct {
Prediction float64 `json:"prediction"`
Confidence float64 `json:"confidence"`
}
func predictHandler(w http.ResponseWriter, r *http.Request) {
var req PredictionRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Here we call your model
prediction := runModel(req.Features)
response := PredictionResponse{
Prediction: prediction,
Confidence: 0.95,
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
func runModel(features []float64) float64 {
// Your inference logic
return 42.0
}
func main() {
http.HandleFunc("/predict", predictHandler)
log.Println("Server starting on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
Popular Go libraries for ML
Gorgonia — a library for building neural networks, similar to PyTorch
GoLearn - classic ML algorithms
Gonum — numerical calculations (analogous to NumPy)
ONNX Runtime Go — launch of ONNX models
TensorFlow Go — Go-bindings for TensorFlow
When to use Go and when to use Python?
Use Go when:
Need high performance in production
Ease of deployment is important (one binary)
Working with competitive loads
Use ready-made models (inference)
Build ML microservices
Stay with Python when:
Conduct research and experiments
Train complex neural networks
Need a rich selection of libraries
Working with a team of data scientists
The most practical option:
Python for training models, experiments, data science
Go for production environment, API, data processing
This approach uses the strengths of each language.
Practical example: recommendation system.
package main
import (
"math"
"sort"
)
type Item struct {
ID int
Features []float64
}
type Recommendation struct {
ItemID int
Score float64
}
// Cosine similarityfunc cosineSimilarity(a, b []float64) float64 {
var dotProduct, normA, normB float64
for i := range a {
dotProduct += a[i] * b[i]
normA += a[i] * a[i]
normB += b[i] * b[i]
}
return dotProduct / (math.Sqrt(normA) * math.Sqrt(normB))
}
// Get recommendationsfunc getRecommendations(userPrefs []float64, items []Item, topN int) []Recommendation {
recommendations := make([]Recommendation, len(items))
for i, item := range items {
recommendations[i] = Recommendation{
ItemID: item.ID,
Score: cosineSimilarity(userPrefs, item.Features),
}
}
// Sort by score
sort.Slice(recommendations, func(i, j int) bool {
return recommendations[i].Score > recommendations[j].Score
})
return recommendations[:topN]
}
func main() {
userPrefs := []float64{0.8, 0.3, 0.9}
items := []Item{
{ID: 1, Features: []float64{0.9, 0.2, 0.8}},
{ID: 2, Features: []float64{0.1, 0.9, 0.2}},
{ID: 3, Features: []float64{0.7, 0.4, 0.9}},
}
recs := getRecommendations(userPrefs, items, 2)
// Displays the top 2 recommendations
}Conclusion
Go can be used to build ML systems, especially in a production environment. Yes, Python remains the standard for training complex models, but Go is an excellent choice for inference, data processing, and creating high-performance services.
The choice of tool always depends on the task. You don't have to give up Python completely, but you shouldn't ignore Go's capabilities in the field of ML.
This and much more can be learned in Codice — analyze everything in detail and consolidate it with practice using real tasks. We offer structured courses in Python, Go, JavaScript and other languages with a focus on practical application.
And if you need support and want to discuss the code with like-minded people, we already have more than 2000 active developers in Telegram channel, where you will always get help, advice and support on the way to learning programming!
🚀 Join the developer community in Codice!
