简化版机器学习项目结构
我将为您提供一个更简洁的项目结构,同时保留核心功能。这个简化版本包含所有必要的组件,但减少了目录层级和文件数量。
简化后的项目结构
ml-project-simple/
├── backend/
│ ├── main.py # FastAPI主应用
│ ├── auth.py # 认证相关
│ ├── models.py # 所有机器学习模型
│ ├── requirements.txt # Python依赖
│ └── Dockerfile # 后端Docker配置
├── frontend/
│ ├── src/
│ │ ├── App.tsx # 主应用组件
│ │ ├── main.tsx # 入口文件
│ │ ├── api.ts # API请求封装
│ │ ├── auth.ts # 认证逻辑
│ │ └── pages/ # 所有页面组件
│ │ ├── Login.tsx
│ │ ├── Dashboard.tsx
│ │ └── algorithms/ # 算法页面
│ │ ├── Linear.tsx
│ │ ├── Logistic.tsx
│ │ ├── RandomForest.tsx
│ │ ├── KMeans.tsx
│ │ └── KNN.tsx
│ ├── package.json
│ ├── tsconfig.json
│ └── Dockerfile # 前端Docker配置
├── docker-compose.yml # 整体部署配置
├── Caddyfile # 反向代理配置
└── README.md # 项目说明
关键文件内容
1. 后端主文件 (backend/main.py)
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from auth import router as auth_router
from models import router as algo_router
app = FastAPI(title="Simple ML API", version="1.0")
# 允许跨域
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 包含路由
app.include_router(auth_router, prefix="/auth")
app.include_router(algo_router, prefix="/algorithms")
@app.get("/")
def home():
return {"message": "Simple ML API is running"}
2. 后端模型文件 (backend/models.py)
from fastapi import APIRouter
import torch
import numpy as np
from sklearn.datasets import make_regression
router = APIRouter()
# 线性回归模型
class LinearModel:
def __init__(self):
self.model = None
def train(self, X, y):
X_tensor = torch.tensor(X, dtype=torch.float32)
y_tensor = torch.tensor(y, dtype=torch.float32).view(-1, 1)
self.model = torch.nn.Linear(X.shape[1], 1)
criterion = torch.nn.MSELoss()
optimizer = torch.optim.SGD(self.model.parameters(), lr=0.01)
for _ in range(1000):
optimizer.zero_grad()
outputs = self.model(X_tensor)
loss = criterion(outputs, y_tensor)
loss.backward()
optimizer.step()
return {"loss": loss.item()}
# 示例数据准备
def prepare_data():
X, y = make_regression(n_samples=100, n_features=1, noise=10, random_state=42)
return {"X": X.tolist(), "y": y.tolist()}
# 路由
linear_model = LinearModel()
@router.get("/linear/data")
def get_data():
return prepare_data()
@router.post("/linear/train")
def train_model(data: dict):
X = np.array(data["X"])
y = np.array(data["y"])
result = linear_model.train(X, y)
return result
3. 前端主应用 (frontend/src/App.tsx)
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import { Layout, Menu } from 'antd'
import { Dashboard, Login } from './pages'
import { Linear, Logistic, RandomForest, KMeans, KNN } from './pages/algorithms'
const { Header, Content, Sider } = Layout
function App() {
return (
<BrowserRouter>
<Layout style={{ minHeight: '100vh' }}>
<Sider>
<Menu theme="dark" mode="inline">
<Menu.Item key="dashboard">Dashboard</Menu.Item>
<Menu.SubMenu key="algorithms" title="Algorithms">
<Menu.Item key="linear">Linear Regression</Menu.Item>
<Menu.Item key="logistic">Logistic Regression</Menu.Item>
<Menu.Item key="randomforest">Random Forest</Menu.Item>
<Menu.Item key="kmeans">K-Means</Menu.Item>
<Menu.Item key="knn">KNN</Menu.Item>
</Menu.SubMenu>
</Menu>
</Sider>
<Layout>
<Header style={{ background: '#fff' }} />
<Content style={{ margin: '16px' }}>
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/login" element={<Login />} />
<Route path="/algorithms/linear" element={<Linear />} />
<Route path="/algorithms/logistic" element={<Logistic />} />
<Route path="/algorithms/randomforest" element={<RandomForest />} />
<Route path="/algorithms/kmeans" element={<KMeans />} />
<Route path="/algorithms/knn" element={<KNN />} />
</Routes>
</Content>
</Layout>
</Layout>
</BrowserRouter>
)
}
export default App
4. 线性回归页面 (frontend/src/pages/algorithms/Linear.tsx)
import { Card, Button, Table, Typography } from 'antd'
import { useState } from 'react'
import api from '../../api'
const { Title } = Typography
export default function LinearRegression() {
const [data, setData] = useState<any>(null)
const [loading, setLoading] = useState(false)
const [trained, setTrained] = useState(false)
const loadData = async () => {
setLoading(true)
try {
const res = await api.get('/algorithms/linear/data')
setData(res.data)
} finally {
setLoading(false)
}
}
const trainModel = async () => {
setLoading(true)
try {
await api.post('/algorithms/linear/train', data)
setTrained(true)
} finally {
setLoading(false)
}
}
return (
<Card loading={loading}>
<Title level={3}>Linear Regression</Title>
<Button onClick={loadData}>Load Data</Button>
{data && (
<>
<Button onClick={trainModel} style={{ marginLeft: 16 }}>
Train Model
</Button>
{trained && <span style={{ marginLeft: 16 }}>Training completed!</span>}
<Table
dataSource={data.X.map((x: number[], i: number) => ({
key: i,
x: x[0],
y: data.y[i]
}))}
columns={[
{ title: 'X', dataIndex: 'x' },
{ title: 'Y', dataIndex: 'y' }
]}
style={{ marginTop: 16 }}
/>
</>
)}
</Card>
)
}
5. Docker Compose 文件
version: '3.8'
services:
backend:
build: ./backend
ports:
- "8000:8000"
environment:
- PORT=8000
restart: unless-stopped
frontend:
build: ./frontend
ports:
- "3000:3000"
restart: unless-stopped
caddy:
image: caddy:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
depends_on:
- backend
- frontend
6. 简化版 Caddyfile
yourdomain.com {
reverse_proxy frontend:3000
}
api.yourdomain.com {
reverse_proxy backend:8000
}
如何运行
-
开发模式:
- 后端:
cd backend && uvicorn main:app --reload
- 前端:
cd frontend && npm start
- 后端:
-
生产部署:
docker-compose up -d --build
简化说明
-
后端简化:
- 将所有模型合并到一个文件
- 减少中间件和依赖
- 简化认证流程
-
前端简化:
- 减少状态管理复杂度
- 合并相似组件
- 简化路由结构
-
部署简化:
- 减少不必要的服务
- 简化配置
这个简化版本保留了核心功能:
- 5种机器学习算法实现
- 基本的前后端交互
- 容器化部署
- 认证功能
- 响应式界面
您可以根据需要在此基础上进行扩展。