import torch
import torch.nn as nn
def train(model, loader, epochs=10):
opt = torch.optim.AdamW(
model.parameters(), lr=3e-4)
loss_fn = nn.CrossEntropyLoss()
model.train()
for epoch in range(epochs):
for x, y in loader:
x, y = x.cuda(), y.cuda()
opt.zero_grad()
loss = loss_fn(model(x), y)
loss.backward()
opt.step()
print(f"epoch {epoch} done")
class ConvNet(nn.Module):
def __init__(self, n_classes=10):
super().__init__()
self.net = nn.Sequential(
nn.Conv2d(3, 32, 3, 1, 1),
nn.ReLU(),
nn.Conv2d(32, 64, 3, 1, 1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Dropout(0.25),
nn.Flatten(),
nn.Linear(64 * 16 * 16, 128),
nn.ReLU(),
nn.Linear(128, n_classes),
)
def forward(self, x):
return self.net(x)
from torchvision import transforms
tfm = transforms.Compose([
transforms.RandomResizedCrop(64),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize(mean, std),
])
train_ds = ImageFolder("train", tfm)
loader = DataLoader(
train_ds, batch_size=64,
shuffle=True, num_workers=4,
)
@torch.no_grad()
def evaluate(model, loader):
model.eval()
correct = total = 0
for x, y in loader:
x, y = x.cuda(), y.cuda()
pred = model(x).argmax(dim=1)
correct += (pred == y).sum()
total += y.size(0)
acc = correct / total
print(f"val acc: {acc:.3%}")
return acc
model.eval()
x = torch.randn(1, 3, 64, 64).cuda()
traced = torch.jit.trace(model, x)
traced.save("model.pt")
# ONNX export for deployment
torch.onnx.export(
model, x, "model.onnx",
input_names=["input"],
output_names=["logits"],
opset_version=17,
)
print("exported model.pt") import torch
import torch.nn as nn
def attention(q, k, v, mask=None):
d_k = q.size(-1)
scores = q @ k.transpose(-2, -1)
scores = scores / d_k ** 0.5
if mask is not None:
scores = scores.masked_fill(
mask == 0, -1e9)
w = torch.softmax(scores, dim=-1)
return w @ v, w
class MultiHeadAttention(nn.Module):
def __init__(self, dim, heads=8):
super().__init__()
self.heads = heads
self.qkv = nn.Linear(dim, 3 * dim)
self.proj = nn.Linear(dim, dim)
def forward(self, x):
B, N, D = x.shape
h = self.heads
qkv = self.qkv(x).reshape(
B, N, 3, h, D // h)
q, k, v = qkv.unbind(2)
out, _ = attention(q, k, v)
out = out.reshape(B, N, D)
return self.proj(out) #include <Eigen/Dense>
#include <array>
#include <cmath>
using Vec7 = std::array<double, 7>;
using Eigen::Matrix4d;
// KUKA iiwa DH parameters
constexpr double A[7] = {
-M_PI_2, M_PI_2, M_PI_2,
-M_PI_2, -M_PI_2, M_PI_2, 0};
constexpr double D[7] = {
0.34, 0.0, 0.40, 0.0,
0.40, 0.0, 0.126};
// One DH link transform
Matrix4d link(double a, double d,
double q) {
double ct = cos(q), st = sin(q);
double ca = cos(a), sa = sin(a);
Matrix4d T;
T << ct, -st*ca, st*sa, 0,
st, ct*ca, -ct*sa, 0,
0, sa, ca, d,
0, 0, 0, 1;
return T;
}
// 7-DOF forward kinematics
Matrix4d fk(const Vec7& q) {
Matrix4d T = Matrix4d::Identity();
for (int i = 0; i < 7; ++i)
T *= link(A[i], D[i], q[i]);
return T;
}
using Eigen::Vector3d;
using Mat67 = Eigen::Matrix<double, 6, 7>;
// Geometric Jacobian at q
Mat67 jacobian(const Vec7& q) {
Mat67 J;
Matrix4d T = Matrix4d::Identity();
Vector3d pe = fk(q).block<3,1>(0,3);
for (int i = 0; i < 7; ++i) {
Vector3d z = T.block<3,1>(0,2);
Vector3d p = T.block<3,1>(0,3);
J.block<3,1>(0,i)=z.cross(pe-p);
J.block<3,1>(3,i)=z;
T *= link(A[i], D[i], q[i]);
}
return J;
}
using Eigen::Matrix3d;
// Damped least-squares IK step
Vec7 ik_step(const Vec7& q,
const Vector3d& goal) {
auto J = jacobian(q).topRows<3>();
Vector3d e = goal -
fk(q).block<3,1>(0,3);
double k = 0.05;
auto Jt = J.transpose();
Vector3d dx = (J*Jt +
k*k*Matrix3d::Identity())
.ldlt().solve(e);
Vec7 dq;
for (int i = 0; i < 7; ++i)
dq[i] = (Jt*dx)(i);
return dq;
} use std::collections::BinaryHeap;
use std::collections::HashMap;
use std::cmp::Ordering;
#[derive(Copy, Clone, Eq, PartialEq)]
struct Node {
cost: u32,
pos: (i32, i32),
}
// min-heap: reverse the ordering
impl Ord for Node {
fn cmp(&self, other: &Self)
-> Ordering {
other.cost.cmp(&self.cost)
}
}
impl PartialOrd for Node {
fn partial_cmp(&self, other: &Self)
-> Option<Ordering> {
Some(self.cmp(other))
}
}
fn heur(a: (i32, i32),
b: (i32, i32)) -> u32 {
let dx = (a.0 - b.0).abs();
let dy = (a.1 - b.1).abs();
(dx + dy) as u32
}
// A* shortest path over a grid
fn astar(
start: (i32, i32),
goal: (i32, i32),
adj: impl Fn((i32, i32))
-> Vec<(i32, i32)>,
) -> Option<u32> {
let mut open = BinaryHeap::new();
let mut best = HashMap::new();
open.push(Node { cost: 0,
pos: start });
best.insert(start, 0u32);
while let Some(cur) = open.pop() {
if cur.pos == goal {
return Some(cur.cost);
}
for nb in adj(cur.pos) {
let g = best[&cur.pos] + 1;
let seen = best.get(&nb)
.copied()
.unwrap_or(u32::MAX);
if g < seen {
best.insert(nb, g);
let f = g
+ heur(nb, goal);
open.push(Node {
cost: f,
pos: nb,
});
}
}
}
None
}