如何利用大模型简化开发过程提高开发效率?

一篇文章让你明白打工人如何利用大模型提高工作效率 随着人工智能(AI)和大模型(如GPT4、BERT等)技术的快速发展,普通职场打工人也可以利用这些强大的工具来提升工作效率,简化日常任务,甚至创新工作方式。本文将详细介绍打工人如何利用大模型提高工作效率,涵盖文本处理、数据分析、自动化任务和决策支持等方面。1. 文档撰写与校对大模型如GPT4具有强大的自然语言生成能力,可以帮助打工人快速撰写各类文档,包括报告、邮件、会议记录等。只需提供关键词或大纲,GPT4就能生成高质量的文本。此外,大模型还可以用于文档校对,自动检查语法错误、拼写错误和格式问题。 阅读详情

史蒂夫・乔布斯曾经把计算机称作 “心灵之自行车”。不过,人们对他这个比喻的背景知之甚少,他是在谈及地球上所有物种移动效率的时候提到的。

图片

由 DALL·E 3 生成的图片,提示 “将计算机想象成心灵的自行车”

秃鹫赢了,位居榜首,超过了其他所有物种。人类排在榜单大约三分之一的位置…… 但是,一旦人类骑上自行车,就能远远超越秃鹫,登顶榜首。这让我深受启发,人类是工具制造者,我们可以制造出将这些固有能力放大到惊人程度的工具。对我来说,计算机一直是思维的自行车,它让我们远远超越了固有的能力。我认为我们只是处于这个工具的早期阶段,非常早期的阶段。我们只走了很短的一段距离,它仍处于形成阶段,但我们已经看到了巨大的变化。我认为,与未来 100 年发生的事情相比,这算不了什么。

—— 史蒂夫・乔布斯(1990)

#01

谨慎乐观

LLM 在加速软件开发方面的作用引发了广泛讨论。有人认为,自动生成的代码质量过低,以至于使用这些代码产生的是负面效果。而另一方面,许多人声称编程的时代已经结束。已经有众多研究试图客观评估 LLM 在诸如 HumanEval 或 MBPP 这样的代码质量基准数据集上的表现。这些评估对于该领域的发展至关重要,但这并非本文的焦点。

本文旨在为开发者,尤其是那些对利用这些模型持保留态度的开发者,提供实用的建议。要注意的是,我相信通过恰当地使用这项技术,一个人的工作效率确实能够实现质的飞跃。

需要明确的是,使用 LLM 并不意味着一定能产出高性能的代码。即便是最先进的模型也会犯下严重的错误。但重要的是要记住,最优秀的人类工程师也难免犯错。这就是我们为什么不会在没有设置防护措施的情况下发布代码,比如进行自动化测试和同行评审。LLM 没有改变最佳实践的本质,但可能改变了实现这些最佳实践的容易度。

图片

描述现在交付代码的过程(图片由 DALL·E 3 生成)

编写高性能代码的速度真的那么重要吗?

如果大多数专业软件工程师的大部分时间都花在了键盘敲击上,我会觉得非常意外。如果真是这样,我们或许会更认真地把 “代码行数” 当作衡量工作表现的一个标准。**我认为,工程师实际上更多的时间是用来决定首先需要编写哪些代码。**目前,LLM 还没有能力进行这种高级的抽象思维 ——OpenAI 和许多其他机构正在努力使这些步骤成为可能,但这很可能需要的不仅仅是增加模型的参数或扩大训练数据,而是需要一种全新的思维方式。然而,LLM 已经能够在很大程度上加速我们的工作中的很大一部分了。

#02

编写高效的函数

让我举个例子来说明,当 LLM 生成了一小段代码后,我们需要采取哪些步骤来优化它,使之变得实用。在地球上的某个点和另一组坐标之间测量距离是地理信息分析中的一个常见任务。想象一下这样的情境。

在这里插入图片描述

首先看到的代码输出是这样的:

import math

def haversine(lat1, lon1, lat2, lon2):
    # Radius of the Earth in kilometers
    R = 6371.0

    # Convert degrees to radians
    lat1_rad = math.radians(lat1)
    lon1_rad = math.radians(lon1)
    lat2_rad = math.radians(lat2)
    lon2_rad = math.radians(lon2)

    # Differences in coordinates
    dlat = lat2_rad - lat1_rad
    dlon = lon2_rad - lon1_rad

    # Haversine formula
    a = math.sin(dlat / 2)**2 + math.cos(lat1_rad) * math.cos(lat2_rad) * math.sin(dlon / 2)**2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))

    # Distance in kilometers
    distance = R * c

    return distance

def find_closest_oil_platform(vessel_lat, vessel_lon, platforms):
    closest_platform = None
    min_distance = float('inf')
    
    for platform in platforms:
        distance = haversine(vessel_lat, vessel_lon, platform['latitude'], platform['longitude'])
        if distance < min_distance:
            min_distance = distance
            closest_platform = platform

    return closest_platform, min_distance

那么,这段代码的质量怎么样呢?

这段代码的质量并不理想。它的问题不少,最明显的是它难以阅读,因为它使用了难以理解和不一致的变量命名,包括大小写的单字符命名。此外,它缺少了文档说明和类型提示,使用了一个不必要且低效的 for 循环,也没有处理一些特殊情况,比如相等距离的问题。

但经过修改之后:

在这里插入图片描述

from typing import Tuple, List
import numpy as np

def haversine_vectorized(vessel_lat: float, vessel_lon: float, platform_lats: np.ndarray, platform_lons: np.ndarray) -> np.ndarray:
    """
    Calculate the Haversine distance between a vessel and multiple platforms in a vectorized manner.

    Parameters:
    - vessel_lat: Latitude of the vessel in decimal degrees.
    - vessel_lon: Longitude of the vessel in decimal degrees.
    - platform_lats: Numpy array of latitudes of oil platforms in decimal degrees.
    - platform_lons: Numpy array of longitudes of oil platforms in decimal degrees.

    Returns:
    - distances: Numpy array of distances from the vessel to each platform in kilometers.
    """
    # Convert decimal degrees to radians
    lat1, lon1, lat2, lon2 = map(np.radians, [vessel_lat, vessel_lon, platform_lats, platform_lons])

    # Haversine formula
    dlat = lat2 - lat1
    dlon = lon2 - lon1
    a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2
    c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1-a))
    r = 6371  # Radius of Earth in kilometers
    return c * r

def find_closest_platform(vessel_lat: float, vessel_lon: float, platform_lats: np.ndarray, platform_lons: np.ndarray) -> Tuple[List[int], float]:
    """
    Finds the closest oil platform(s) to a vessel given arrays of platform latitudes and longitudes, handling equidistant platforms.

    Parameters:
    - vessel_lat: Latitude of the vessel in decimal degrees.
    - vessel_lon: Longitude of the vessel in decimal degrees.
    - platform_lats: Numpy array of latitudes for oil platforms.
    - platform_lons: Numpy array of longitudes for oil platforms.

    Returns:
    - A tuple containing a list of indices of the closest platforms and the distance to them in kilometers.
    """
    # Calculate distances to all platforms
    distances = haversine_vectorized(vessel_lat, vessel_lon, platform_lats, platform_lons)
    
    # Find the minimum distance
    min_distance = np.min(distances)
    
    # Find all indices with the minimum distance
    closest_indices = np.where(distances == min_distance)[0].tolist()

    # Return the indices of all closest platforms and the minimum distance
    return closest_indices, min_distance

改进后的代码有了明显提升。它变得更容易阅读了,增加了文档说明和类型提示,并且用更高效的向量计算方式替换了原有的 for 循环。

但是,代码的 “好坏”,更重要的是,它是否满足需求这些都取决于代码将要运行的具体环境。要知道,我们无法仅凭几行代码就能有效评估其质量,这一点对人类如此,对 LLM 也是如此。

比如说,这段代码的准确度是否满足用户的预期?它会被频繁运行吗?是一年一次,还是每微秒一次?使用的硬件条件如何?预期的使用量和规模是否值得我们去追求那些细小的优化?在考虑到你的薪资之后,这样做是否划算?

让我们在上述因素的基础上来评估这段代码。

在准确性方面,虽然半正矢公式(haversine formula)表现不错,但并非最佳选择,因为它将地球视为一个完美的球体,而实际上地球更接近于一个扁球体。在需要跨越巨大距离进行毫米级精确测量时,这种差异变得非常重要。如果真的需要这样的精确度,虽然有更精确的公式(如 Vincenty 公式)可用,但这会带来性能上的折中。因为对于这段代码的用户而言,毫米级的精确度并不是必须的(事实上,由于卫星图像导出的船舶坐标的误差,这种精度也并不相关),所以在准确性方面,半正弦函数是一个合理的选择。

代码运行得够快吗?考虑到只需要对几千个海上石油平台计算距离,特别是通过向量计算方法,这种计算是非常高效的。但如果应用场景变成了计算与岸边任意点的距离(岸线上有数以亿计的点),那么采用 “分而治之” 的策略可能会更加合适。在实际应用中,考虑到节约计算成本的需要,这个函数设计为在一个尽可能配置低的虚拟机上每天运行约 1 亿次。

基于这些详细的背景信息,我们可以认为上面的代码实现是合理的。这也意味着,在代码最终合并前,它应该先经过测试(我通常不推荐仅依赖 LLM 进行测试)和人工同行评审。

#03

加速前进

像之前那样利用 LLM 自动生成实用的函数不仅可以节省时间,而且当你开始利用它们来生成整套的库、处理模块间的依赖、撰写文档、实现可视化(通过多模态能力)、编写 README 文件、开发命令行接口等时,它们带来的价值将会成倍增长。

我们来试着从零开始,借助 LLM 的广泛辅助,创建、训练、评估并推断一个全新的计算机视觉模型。以一篇最近发表的论文为例,“通过深度学习识别 Sentinel-2 图像中船舶尾迹组件的关键点方法”(Del Prete 等人,IEEE GRSL,2023),这篇论文就是我们前进的动力和灵感来源。

在这里插入图片描述

Sentinel-2 卫星图像中显示的一艘船及其尾流。

为什么我们需要关心船舶在卫星图像中的行进方向,这项任务有什么难点呢?

通过静态图像识别船只的航行方向,对于那些需要监控水域中人类活动的组织来说,是极其宝贵的信息。比如,如果一艘船正朝向一个海洋保护区行进,这可能意味着需要警觉或者采取拦截措施。通常,全球范围内公开的卫星图像的分辨率不足以精确判断一艘船的朝向,尤其是那些在图像上只占据几个像素的小型船只(例如,Sentinel-2 的图像分辨率为 10 米 / 像素)。然而,即便是小型船只留下的水波纹也可能相当明显,这就为我们提供了一个判断船只朝向和行进方向的线索,即使船的尾部无法直接识别。

这项研究之所以引人注目,是因为它采用的模型基于 EfficientNetB0,这是一个足够小的模型,能够在不花费太多计算资源的情况下进行大规模应用。虽然我没有找到具体的代码实现,但作者公开了包括标注在内的数据集,这是值得赞赏的一步。

开始我们的探索吧!

如同启动任何新的机器学习项目一样,首先对数据进行可视化是极富启发性的一步。
在这里插入图片描述

import os
import json
from PIL import Image, ImageDraw
import matplotlib.pyplot as plt
import seaborn as sns

# Define the path to your data directory
data_dir = "/path/to/your/data"  # Adjust this to the path of your data directory
annotations_dir = os.path.join(data_dir, "annotations")
images_dir = os.path.join(data_dir, "imgs")

# Initialize Seaborn for better visual aesthetics
sns.set(style="whitegrid", palette="muted")

# Create a list to hold file paths for images and their corresponding annotations
image_files = []
annotation_files = []

# Loop through the annotations directory to get the list of annotation files
for annotation_file in os.listdir(annotations_dir):
    if annotation_file.endswith(".json"):
        annotation_path = os.path.join(annotations_dir, annotation_file)
        image_file = annotation_file.replace(".json", ".png")  # Assuming image file names match annotation file names
        image_path = os.path.join(images_dir, image_file)

        # Check if the corresponding image file exists
        if os.path.exists(image_path):
            annotation_files.append(annotation_path)
            image_files.append(image_path)

# Plotting
num_examples = min(len(image_files), 10)  # Limiting to 10 examples for visualization
fig, axes = plt.subplots(2, 5, figsize=(20, 8))

for idx, (image_path, annotation_path) in enumerate(zip(image_files[:num_examples], annotation_files[:num_examples])):
    # Load the image
    img = Image.open(image_path).convert("RGB")  # Ensure the image is treated as RGB
    draw = ImageDraw.Draw(img)

    # Load the corresponding annotations and draw keypoints
    with open(annotation_path, 'r') as f:
        annotations = json.load(f)
        for point in annotations["tooltips"]:
            x, y = point["x"], point["y"]
            # Draw keypoints in cyan for visibility
            draw.ellipse([(x-10, y-10), (x+10, y+10)], fill='cyan', outline='black')

    # Plot the image with keypoints
    ax = axes[idx // 5, idx % 5]
    ax.imshow(img)
    ax.axis('off')
    ax.set_title(f"Image {idx+1}")

plt.tight_layout()
plt.show()

结果如下:

在这里插入图片描述
Sentinel-2 卫星图像中的船只和尾流关键点注释(青色)样本。

结果展示了几个关键的发现:首先,不同图片中标注的关键点(青色点)数量不一;其次,这些图像都是灰度的,并且形状各异;第三,尽管样本量不大,但其内部差异性却相当大。在明确了这些基础之后,我们接下来将编写用于加载数据集、定义神经网络、进行训练和验证的代码。在请求代码之前,我们会先向 LLM 提供一些背景信息。

在这里插入图片描述

这导致了以下输出:

import os
import json
import torch
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms
from torchvision.io import read_image
from typing import Tuple, List

class WakeDataset(Dataset):
    """
    Custom Dataset for loading wake detection imagery and annotations, with preprocessing for EfficientNet.
    Images are grayscale and will be converted to three-channel images for model compatibility.
    """
    
    def __init__(self, annotations_dir: str, images_dir: str, transform=None):
        """
        Initializes the dataset with paths to annotations and images directories, and a transform.

        Parameters:
        - annotations_dir: Path to the directory containing annotation JSON files.
        - images_dir: Path to the directory containing grayscale image files.
        - transform: A torchvision.transforms transform to be applied on a sample.
        """
        self.annotations_dir = annotations_dir
        self.images_dir = images_dir
        self.transform = transform if transform else self.default_transform()
        self.annotations = self._load_annotations()

    def default_transform(self):
        """
        Defines the default transform to resize images, convert them to three-channel format, and to tensors.

        Returns:
        - A torchvision.transforms composition for image preprocessing.
        """
        return transforms.Compose([
            transforms.Resize((224, 224)),  # Resize to the input size for EfficientNet
            transforms.Grayscale(num_output_channels=3),  # Convert grayscale to three-channel
            transforms.ConvertImageDtype(torch.float),  # Ensures image is a float tensor
        ])

    def _load_annotations(self) -> List[Tuple[str, List[int]]]:
        """
        Loads and filters annotations with at least 2 keypoints.

        Returns:
        - A list of tuples, where each tuple contains the image filename and its keypoints.
        """
        annotations = []
        for filename in os.listdir(self.annotations_dir):
            if not filename.endswith('.json'):
                continue
            filepath = os.path.join(self.annotations_dir, filename)
            with open(filepath, 'r') as f:
                data = json.load(f)
                if len(data['tooltips']) >= 2:  # Filter annotations with at least 2 keypoints
                    keypoints = [item for sublist in [[kp['x'], kp['y']] for kp in data['tooltips']] for item in sublist]
                    annotations.append((filename.replace('.json', '.png'), keypoints))
        return annotations

    def __len__(self) -> int:
        """
        Returns the number of items in the dataset.
        """
        return len(self.annotations)

    def __getitem__(self, idx) -> Tuple[torch.Tensor, torch.Tensor]:
        """
        Retrieves an item from the dataset at the specified index, with preprocessing for EfficientNet.

        Parameters:
        - idx: Index of the item to retrieve.

        Returns:
        - A tuple containing the preprocessed image tensor and its corresponding keypoints tensor.
        """
        img_name, keypoints = self.annotations[idx]
        img_path = os.path.join(self.images_dir, img_name)
        image = read_image(img_path)  # Load image
        keypoints = torch.tensor(keypoints + [0] * (6 - len(keypoints)), dtype=torch.float)  # Pad keypoints
        if self.transform:
            image = self.transform(image)
        return image, keypoints

最终得到的代码看起来还算合理,并且似乎注意到了问题的一些细节。虽然不是完美的(例如,选择在 default_transform 中将图像从灰度转为 RGB 颜色模式是个奇怪的决定,我个人更倾向于使用 pathlib 而非 os。listdir),但我们现在可以先放下这些细节不谈。
在这里插入图片描述

import torch
import torch.nn as nn
from torchvision import models
from typing import Tuple

class EfficientNetB0KeypointDetector(nn.Module):
    """
    A custom EfficientNet-B0 model for keypoint detection in grayscale images.
    The network modifies the input layer to accept single-channel images and 
    adds a custom output layer for predicting a fixed number of keypoints.
    """

    def __init__(self, num_keypoints: int = 3):
        """
        Initializes the model.

        Parameters:
        - num_keypoints: The number of keypoints to predict. Default is 3, 
                         corresponding to the maximum number of keypoints in the dataset.
        """
        super(EfficientNetB0KeypointDetector, self).__init__()
        self.num_keypoints = num_keypoints
        # Load a pre-trained EfficientNet-B0
        self.efficientnet_b0 = models.efficientnet_b0(pretrained=True)
        
        # Modify the first convolutional layer to accept single-channel (grayscale) images
        original_first_conv = self.efficientnet_b0.features[0][0]
        self.efficientnet_b0.features[0][0] = nn.Conv2d(
            in_channels=1, 
            out_channels=original_first_conv.out_channels, 
            kernel_size=original_first_conv.kernel_size, 
            stride=original_first_conv.stride, 
            padding=original_first_conv.padding, 
            bias=False)

        # Modify the classifier to predict keypoints (num_keypoints * 2 because x, y for each keypoint)
        self.efficientnet_b0.classifier = nn.Linear(
            in_features=self.efficientnet_b0.classifier[1].in_features, 
            out_features=num_keypoints * 2)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        """
        Forward pass of the network.

        Parameters:
        - x: Input tensor of shape (batch_size, 1, 224, 224)

        Returns:
        - A tensor of shape (batch_size, num_keypoints * 2) representing the predicted keypoints.
        """
        return self.efficientnet_b0(x)

# Example usage
if __name__ == "__main__":
    model = EfficientNetB0KeypointDetector()
    print(model)

    # Example input tensor (batch_size, channels, height, width)
    example_input = torch.randn(1, 1, 224, 224)
    output = model(example_input)
    print(output.shape)  # Expected shape: (1, 6) for 3 keypoints (each with x, y coordinates)

在这里插入图片描述

import os
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from dataset import WakeDataset, get_dataloader  # Assuming dataset.py is in the same directory
from net import EfficientNetB0KeypointDetector
from torchvision import transforms
import wandb

# Initialize Weights & Biases
wandb.init(project="wake_model_llm_assist", entity="your_wandb_entity", mode="offline")

def custom_collate_fn(batch):
    """
    Custom collate function to pad keypoints to a fixed size.
    
    Parameters:
    - batch: A list of tuples (image, keypoints).
    
    Returns:
    - Batched images and keypoints with padding as necessary.
    """
    images, keypoints = zip(*batch)
    images = torch.stack(images, 0)
    max_keypoints = 3 * 2  # Maximum number of keypoints (3) times 2 for (x, y)
    padded_keypoints = [torch.cat((kp, torch.zeros(max_keypoints - len(kp)))) for kp in keypoints]
    keypoints = torch.stack(padded_keypoints, 0)
    return images, keypoints

def train_one_epoch(model: nn.Module, dataloader: DataLoader, optimizer: optim.Optimizer, device: torch.device):
    """
    Trains the model for one epoch.
    
    Parameters:
    - model: The neural network model.
    - dataloader: DataLoader providing the training data.
    - optimizer: Optimizer used for model training.
    - device: The device to train on.
    """
    model.train()
    total_loss = 0.0
    for images, keypoints in dataloader:
        images, keypoints = images.to(device), keypoints.to(device)
        optimizer.zero_grad()
        outputs = model(images)
        loss = nn.MSELoss()(outputs, keypoints)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
    
    average_loss = total_loss / len(dataloader)
    wandb.log({"train_loss": average_loss})

def evaluate(model: nn.Module, dataloader: DataLoader, device: torch.device):
    """
    Evaluates the model on the validation set.
    
    Parameters:
    - model: The neural network model.
    - dataloader: DataLoader providing the validation data.
    - device: The device to evaluate on.
    """
    model.eval()
    total_loss = 0.0
    with torch.no_grad():
        for images, keypoints in dataloader:
            images, keypoints = images.to(device), keypoints.to(device)
            outputs = model(images)
            loss = nn.MSELoss()(outputs, keypoints)
            total_loss += loss.item()
    
    average_loss = total_loss / len(dataloader)
    wandb.log({"val_loss": average_loss})

def main():
    # Setup
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model = EfficientNetB0KeypointDetector().to(device)
    optimizer = optim.Adam(model.parameters(), lr=1e-3)

    # DataLoaders
    train_dataloader = get_dataloader('path/to/train/annotations', 'path/to/train/images', batch_size=4, transform=transforms.ToTensor(), collate_fn=custom_collate_fn)
    val_dataloader = get_dataloader('path/to/val/annotations', 'path/to/val/images', batch_size=4, transform=transforms.ToTensor(), collate_fn=custom_collate_fn)

    # Training loop
    for epoch in range(num_epochs):
        train_one_epoch(model, train_dataloader, optimizer, device)
        evaluate(model, val_dataloader, device)
        # Log model checkpoints, images, or other metrics as needed
        wandb.log({})

if __name__ == "__main__":
    main()

当我开始尝试运行代码时,遇到了一系列与张量形状不匹配相关的问题(想起了之前 RGB 与灰度图像的差异以及自定义 collate 函数的问题)。我尝试了几分钟的调试,但最终选择将所有模块代码复制到提示框里,让它帮我一起找出问题所在。

在这里插入图片描述

这样做有效解决了所有挂起的问题,我随即开始了模型的训练…… 但训练速度慢得出奇。这时我才意识到我没有利用 Apple 芯片上的 Metal 性能着色器(MPS)后端。虽然我平时不太在个人电脑上训练模型,MPS 对我还比较新,但我还是决定添加一个条件判断来使用它。

鉴于训练数据量适中(共 581 张图片),加上 EfficientNet 已经在 ImageNet 上进行了预训练,我决定进行 1000 个周期的训练。

在这里插入图片描述

500 个周期后,train_loss 仍在减少,但验证损失似乎已经收敛(至少对于快速评估而言足够收敛)。图像是根据权重和偏差复制的。

值得注意的是,尽管存在一些已经在卫星图像上进行预训练的基础模型(相对于 ImageNet),这些模型很可能对这项任务更有效,但这些网络体积比 EfficientNet 大得多,因此训练速度更慢(而且太新,还没被 LLM 训练数据集包括)。

现在,让我们编写一个推理脚本和一个命令行界面(CLI),来测试我们刚训练好的模型。

在这里插入图片描述

import torch
from torchvision import transforms
from PIL import Image
import matplotlib.pyplot as plt
import click

# Assuming net.py contains the EfficientNetB0KeypointDetector class
# and dataset.py contains the transforms used during training
from net import EfficientNetB0KeypointDetector
from dataset import WakeDataset  # Modify as necessary to import transforms

def load_model(model_path):
    """Load the trained model from a file."""
    model = EfficientNetB0KeypointDetector()
    model.load_state_dict(torch.load(model_path))
    model.eval()  # Set the model to inference mode
    return model

def preprocess_image(image_path, transform):
    """Load and preprocess an image."""
    image = Image.open(image_path).convert("L")  # Assuming grayscale conversion as in your dataset
    image = transform(image)
    # Add batch dimension (BxCxHxW)
    image = image.unsqueeze(0)
    return image

def plot_keypoints(image, keypoints):
    """Plot keypoints on the image."""
    plt.imshow(image.squeeze(), cmap='gray')  # Remove batch dimension and show image
    plt.scatter(keypoints[:, 0], keypoints[:, 1], s=50, marker='.', c='red')
    plt.show()

@click.command()
@click.argument('model_path', type=click.Path(exists=True))
@click.argument('image_path', type=click.Path(exists=True))
def run_inference(model_path, image_path):
    """Run inference on an image using a trained model."""
    # Use the same transforms as during training
    transform = transforms.Compose([
        transforms.Resize((224, 224)),
        transforms.ToTensor(),
        transforms.Grayscale(num_output_channels=3),
    ])
    
    model = load_model(model_path)
    image = preprocess_image(image_path, transform)
    
    # Perform inference
    with torch.no_grad():
        keypoints = model(image)
        keypoints = keypoints.view(-1, 2).cpu().numpy()  # Reshape and convert to numpy for plotting
    
    # Load original image for plotting
    original_image = Image.open(image_path).convert("L")
    plot_keypoints(original_image, keypoints)

if __name__ == '__main__':
    run_inference()

让我们开始吧!
在这里插入图片描述

在这里插入图片描述

虽不完美,但对于第一次通过来说是合理的。

在这里插入图片描述

你可以在 GitHub 上找到包括所有模块、模型及权重(第 500 周期的)和一个 readme 的完整代码。我花了不到一个小时就生成了整个库,这个过程比写这篇文章花费的时间要少得多。所有这些工作都是在我的个人开发环境中完成的:MacBook Air M2 + VS Code + Copilot + 保存时自动格式化(使用 black、isort 等)+ 一个 Python 3.9.6 的虚拟环境(.venv)。

GitHub:https://github.com/pbeukema/wakemodel_llmassist

学到的教训

  • 向模型提供尽可能多的相关上下文,帮助其解决任务。要记住,模型缺少许多你可能认为理所当然的假设。
  • LLM 生成的代码通常远非完美,预测其失败的方式也颇具挑战。因此,在 IDE 中有一个辅助工具(比如 Copilot)非常有帮助。
  • 当你的代码高度依赖 LLM 时,要记得编写代码的速度往往是限制因素。避免请求重复且不需要任何改动的代码,这不仅浪费能源,也会拖慢你的进度。
  • LLM 很难 “记住” 它们输出的每一行代码,经常需要提醒它们当前的状态(特别是当存在跨多个模块的依赖时)。
  • 对 LLM 生成的代码保持怀疑态度。尽可能多地进行验证,使用测试、可视化等手段。并且在重要的地方投入时间。相比于神经网络部分,我在 haversine 函数上花费了更多的时间(因为预期规模对性能的要求较高),对于神经网络,我更关注的是快速发现失败。

#04

LLM 与工程领域的未来

唯有变化是永恒的。

—— 赫拉克利特

在 LLM 引发的热潮和巨额资金流动的背景下,人们很容易一开始就期待完美。然而,有效利用这些工具,需要我们勇于尝试、学习并做出调整。

LLM 是否会改变软件工程团队的根本结构呢?可能吧,我们现在只是新世界的门前小道。但 LLM 已经使代码的获取变得更加民主化了。即使是没有编程经验的人,也能快速而容易地构建出功能性原型。如果你有严格的需求,将 LLM 应用在你已经熟悉的领域或许更为明智。根据我个人的经验,LLM 能够使得编写高效代码所需的时间缩短约 90%。如果你发现它们一直输出低质量的代码,那么也许是时候重新审视你的输入了。

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范
  • …

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署
  • …

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建
  • …

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案
  • …

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费】

在这里插入图片描述

【AI测试时代】如何使用大模型辅助测试,提高效率 DashScope(模型服务灵积)是一个基于“模型即服务”(Model-as-a-Service,MaaS)理念的模型服务平台,由阿里云提供。该平台致力于为AI应用开发者提供丰富多样的模型选择,并通过标准化API接口提供包括模型推理、模型微调训练在内的多种模型服务。DashScope的服务以模型为中心,支持AI开发者通过简单的API调用直接集成大模型的能力,同时也支持对模型进行训练微调,实现模型的定制化。 阅读详情

相关推荐

STM32 SPI驱动TFT LCD实战:时序配置与硬件协同

SPI(串行外设接口)是一种高速、全双工、同步串行通信协议,广泛应用于微控制器与显示模组等外设的数据交互。其核心依赖时钟极性(CPOL)与时钟相位(CPHA)组合定义的四种工作模式,直接影响数据采样可靠性;而片选(NSS)与MOSI/SCLK等信号的硬件映射,则决定了多设备共总线下的通信稳定性。在TFT LCD驱动场景中,SPI凭借低开销、高吞吐优势成为主流选择,尤其适配ST7789、ILI9341等集成显示控制器的模块。本文聚焦STM32L系列MCU通过SPI2驱动1.3寸LCD的完整链路,涵盖Mode

php55的博客 1211

聊聊大模型如何为敏捷研发提效

随着大模型技术的风起云涌,各家大厂和研究机构纷纷开始了大模型在效能提升方面的尝试。复盘一下鼎叔基于前期团队实践的心得,也和不少同行交流过,思路还是很被认同的。 大模型在研发效能领域的实践,有喜有忧。 喜的是,自然语言表达能力的革新,值得把所有依赖教练推动的敏捷方案都重做一遍; 忧的是,如果不掌握敏捷研发的本质理论,不懂敏捷,各种大模型提效实践的成功概率会非常低

Eyemon的博客 1672

国标GB28181视频平台EasyGBS国标平台设备播放断流现象的问题解决方案

于是排查代码发现,当设备网络较差时,设备会断流,超过指定的时间30s(EasyGBS平台默认值),就会主动清除流媒体服务,但是redis中的流数据还在,而当设备在录像时,自动保活会从redis中取保活流数据,所以就会出现设备状态显示正在播放,但是流已经消失的情况。有用户反馈,在安防视频监控EasyGBS运行时,接入的设备刚开始可以正常播放,开启云端录像后,也没有停止和重播的操作,但是出现了视频流断流的现象。在设备进行播放保活时,对流信息进行判断,添加一个最后的处理流时间,如果超过指定时间就自动重新拉流。

EasyNTS的博客 436

大模型在研发效率提升方面的应用与实践 | 新程序员

【导读】在当今软件开发和科学研究领域,项目的复杂性日益增加,提升研发效率已成为行业迫切需求。本文深入探讨了大模型技术在研发效率提升方面的应用与实践,以实战摸索的方式,真实揭示了大模型究竟能够如何助力企业实现数智化转型。本文精选自《新程序员007:大模型时代的开发者》,《新程序员 007》聚焦开发者成长,其间既有图灵奖得主 Joseph Sifakis、前 OpenAI 科学家 Joel Lehm...

优快云资讯 946

nnDetection实战:手把手教你用Python在自家电脑上跑通第一个肺结节检测模型

本文详细介绍了如何使用nnDetection框架在普通电脑上实现肺结节检测模型的搭建与运行。从环境配置、数据预处理到模型训练与推理,手把手教你完成医学图像检测的全流程,特别适合初学者入门医学AI领域。

weixin_32377497的博客 331

图像分割 - 使用Mask R-CNN模型在COCO数据集上进行图像分割任务

图像分割是计算机视觉领域的一个重要任务,它旨在将图像中的每个像素分类为对象或背景。Mask R-CNN是一种基于区域的卷积神经网络,可用于图像分割任务。它是Faster R-CNN的扩展,将目标检测与图像分割结合起来,能够同时检测和分割对象。在本博客中,我们将使用Mask R-CNN模型在COCO数据集上进行图像分割任务。我们将介绍如何下载和准备COCO数据集,以及如何使用Mask R-CNN模型进行训练和推理。

斌擎科技 1190

使用大模型提效程序员工作

通过在接手其他语言的项目中使用大模型、生成脚本辅助日志查询、根据接口文档使用大模型直接生成Java Bean代码以及学习新技术这四个场景的实践,我们可以更快地理解代码、更快地查找线上问题,以及减少编码时间。比如:你可以输入一段 Lua 脚本,询问大模型,这段脚本的意思,还可以让它详细解释每行代码的意思,让我们更快接手一个我们不熟悉编程语言写的项目。比如:我们需要接入其他人写的接口,他们只给了我们一个文档,文档中有表格,列举了每个字段的类型和意思,以及返回的一个示例 Json。

伍六七的博客 868

非机动车闯红灯检测与自动录像系统实战(YOLO+追踪+红绿灯感知)

本文聚焦非机动车(如电动车、自行车)闯红灯行为的智能识别系统构建,结合 YOLO 检测模型、追踪算法(如 DeepSORT)、红绿灯状态感知与区域判断逻辑,构建完整的违章行为识别与证据录像系统。文章涵盖数据采集、模型选型、红绿灯触发机制、闯红逻辑判定、视频自动保存等核心环节,辅以 Jetson/RK3588 平台部署与工程实测,适用于城市交通监控、智慧路口管控等真实场景。

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 1285

如何用大模型提升学习效率?(非常详细)零基础入门到精通,收藏这一篇就够了

自从2022年底ChatGPT横空出世以来,在过去的十几个月里,生成式人工智能的浪潮席卷并改变着各行各业。2023年一月,在线课程供应商Study.com曾向1000名18岁以上的学生发起的一项调查显示,当时就已经有超过89%的学生使用ChatGPT来完成家庭作业,53%的学生用ChatGPT写论文。无独有偶,在线杂志Intelligent同时期针对在校大学生的一项研究也显示,有60%以上的受访者表示一半以上的作业都使用了ChatGPT。图片来自Intelligent 2023年1月的调查研究。

Javachichi的博客 1577

【C2000系列DSP的Bootloader详解】实现过程、流程图与示例代码

C2000 Bootloader 的核心逻辑可概括为 “初始化→选模式→加载程序→校验→跳转” 五步。对于小白来说,无需纠结底层寄存器配置(驱动库已封装),重点理解 “启动流程” 和 “数据传输 + 校验” 的核心思想即可。 通过本文的流程图和示例代码,相信你已经掌握了 C2000 Bootloader 的核心原理。实际开发中,可基于 TI 提供的 Bootloader 示例(C2000Ware 中自带)进行修改,快速适配自己的硬件和应用场景。

昔时扬尘处 376

ESP32-S3模组上跑通esp32-camera(32)

ESP32-S3模组上跑通esp32-camera(32)

phmatthaus的专栏 773

如何用大模型提升数据开发各个环节效率

如何用大模型提升数据开发各个环节效率一点感受,大模型做一个完整的技术方案,很难;但如果大模型改造我们工作流程中的每一个环节,大有可为。也就是,人类专家负责构建业务流程,大模型来完成流程环节,比幻想大模型一下子做成什么事情,可行的多。这篇文章从数据仓库的日常研发视角出发,分析大模型可以对每一个环节做哪些效率的提升。## |0x00 推理模型和非推理模型的区别我们都知道要用DeepSeek的R1,这...

云祁QI 335

wvp gb28181 pro 平台国标级连功能说明

国标28181不同平台之间支持两种连接方式,平级和上下级,WVP目前支持向上级级联。

zengliguang的专栏 3888

【AI大模型实践教程】如何利用大模型简化开发过程提高开发效率?

史蒂夫・乔布斯曾经把计算机称作 “心灵之自行车”。不过,人们对他这个比喻的背景知之甚少,他是在谈及地球上所有物种移动效率的时候提到的。由 DALL·E 3 生成的图片,提示 “将计算机想象成心灵的自行车”秃鹫赢了,位居榜首,超过了其他所有物种。人类排在榜单大约三分之一的位置…… 但是,一旦人类骑上自行车,就能远远超越秃鹫,登顶榜首。这让我深受启发,人类是工具制造者,我们可以制造出将这些固有能力放大到惊人程度的工具。对我来说,计算机一直是思维的自行车,它让我们远远超越了固有的能力。

xxue345678的博客 1344

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

大模型助力开发,简化流程,提高效率

在当今这个快节奏的时代,时间就是金钱,效率就是生命。尤其是在软件开发领域,如何在有限的时间内,高效地完成项目,是每个开发者都需要面对的挑战。而大模型的运用,正是解决这一问题的关键。大模型,是一种基于大数据和人工智能技术的新型开发工具。它通过学习大量的数据,形成一套高度智能化的开发模式,能够帮助开发者快速地构建和优化软件。无论是在项目管理、代码编写、测试调试,还是在后期维护中,大模型都能发挥巨大的作用,大大提高开发效率。

2401_84495725的博客 1296

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

【编程提效】如何利用AI大模型提高编程效率:经典教程

自动代码补全是指在编写代码时,IDE(集成开发环境)利用AI大模型根据上下文预测并建议可能需要的代码片段。这种功能不仅可以减少打字时间,还能帮助开发者更专注于逻辑思考。ChatMoss & ChatGPT中文版代码生成工具利用AI大模型,根据开发者提供的基本信息自动生成代码。这在处理重复性任务时尤为有用,如生成数据库访问代码。AI大模型不仅可以生成文档,还具备解读文档的能力。这意味着AI可以帮助开发者快速理解现有文档的内容和结构,尤其是在面对复杂或庞大的项目时。

万物皆有灵 1129

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

使用大模型生成可用代码:提高开发效率的新途径

大模型在代码生成领域的应用,标志着软件开发进入了一个新的智能化阶段。尽管仍面临诸如代码质量控制、模型解释性等挑战,但其在提高开发效率、缩短迭代周期方面的潜力不容忽视。随着技术的不断成熟与优化,大模型将成为开发者不可或缺的辅助工具,推动软件开发迈入更加高效、智能的新纪元。​。

xxue345678的博客 2685

大模型能提高工作效率吗?

大模型能够快速阅读长篇文档,并生成内容的摘要,帮助用户节省阅读时间,迅速把握文档的核心信息。

python1234_的博客 2882

大模型时代,如何用API调用提升开发效率?

最新接入DeepSeek-V3模型,点击下载最新版本InsCode AI IDE 大模型时代,如何用API调用提升开发效率? 随着人工智能技术的飞速发展,大模型已经成为推动软件开发领域变革的重要力量。从自然语言处理到图像识别,再到代码生成,大模型的强大能力正在改变开发者的工作方式。然而,对于许多编程新手或中小型团队来说,直接调用大模型API可能显得复杂且耗时。那么,如何在实际开发中更高效地利用大模...

SilverfoxFalcon45的博客 946

几款提高开发效率的Idea 插件

通义灵码,是一款基于通义大模型的智能编码辅助工具,提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码注释生成、代码解释、研发智能问答、异常报错排查等能力,并针对阿里云 SDK/API 的使用场景调优,为开发者带来高效、流畅的编码体验。开发代码过程中经常会有一些需要提交到代码仓库的文件,比如java文件生成的.class、.jar 等,如果将编译后的文件都提交到代码库那么代码库会很大,关键是没有必要。免费开源的mybatis sql查看器,零代码入侵,支持mybatis-plus。

我就是我不一样的美男子! 2422

大模型API调用的革新:如何简化编程与提升开发效率

最新接入DeepSeek-V3模型,点击下载最新版本InsCode AI IDE 标题:大模型API调用的革新:如何简化编程与提升开发效率 在当今数字化时代,人工智能(AI)技术的迅猛发展为各行各业带来了前所未有的机遇。特别是在软件开发领域,大模型API的应用正逐渐改变着传统的编程方式。通过大模型API,开发者能够快速实现复杂的任务,如自然语言处理、图像识别、语音合成等,而无需深入了解底层算法和架...

inscode_087的博客 562

借助AI大模型简化MySQL安装与开发流程

开发AI智能应用,就下载InsCode AI IDE,一键接入DeepSeek-R1满血版大模型! 标题:借助AI大模型简化MySQL安装与开发流程 在当今数字化时代,数据库管理已成为各类应用开发的核心环节。而作为全球最流行的开源关系型数据库之一,MySQL凭借其高性能、可靠性和易用性,成为了开发者们的首选工具。然而,对于初学者来说,MySQL的安装和配置可能显得复杂且耗时。此外,在实际开发中,如...

JetRaven12的博客 667

讯飞星火大模型C接入Demo:一款简化API接入的开发利器

讯飞星火大模型C#接入Demo:一款简化API接入的开发利器 去发现同类优质开源项目:https://gitcode.com/ 项目核心功能/场景 简化讯飞星火大模型API接入,提升开发者工作效率。 项目介绍 在现代软件开发领域,自然语言处理技术已成为不可或缺的一环。讯飞星火大模型C#接入Demo正是为了满足这一需求而诞生的工具。它旨在帮助开发者通过简单的步骤,快速接入讯飞星火大模型的API,从而...

gitblog_06787的博客 837

探索大模型API的无限可能:如何通过智能化工具提升开发效率

最新接入DeepSeek-V3模型,点击下载最新版本InsCode AI IDE 探索大模型API的无限可能:如何通过智能化工具提升开发效率 在当今快速发展的科技时代,人工智能(AI)和机器学习(ML)已经逐渐渗透到各个行业。其中,大模型API的出现为开发者带来了前所未有的便利。这些强大的API不仅能够处理复杂的任务,还能显著提高开发效率。然而,对于许多编程新手或非专业开发者来说,调用和使用这些A...

inscode_043的博客 904

探索大模型API的无限可能:如何利用智能化工具简化编程

最新接入DeepSeek-V3模型,点击下载最新版本InsCode AI IDE 探索大模型API的无限可能:如何利用智能化工具简化编程 在当今快速发展的科技时代,人工智能(AI)和大模型技术正在深刻改变各行各业的工作方式。特别是在软件开发领域,大模型API的应用为开发者带来了前所未有的便利与效率。本文将探讨如何通过智能化工具如InsCode AI IDE来简化大模型API的调用过程,并展示其应用...

inscode_066的博客 690

大模型API调用新时代:如何通过智能工具简化开发流程

最新接入DeepSeek-V3模型,点击下载最新版本InsCode AI IDE 标题:大模型API调用新时代:如何通过智能工具简化开发流程 随着人工智能技术的飞速发展,大模型API的应用场景日益广泛。从自然语言处理到图像识别,从语音合成到代码生成,大模型API正在改变各行各业的工作方式。在软件开发领域,这一变革尤为显著。本文将探讨如何通过智能化工具简化大模型API的调用过程,并重点介绍一款能够极...

inscode_016的博客 915
上一篇: 物流业面临大模型挑战:是机遇还是颠覆?
下一篇: 大模型要抢我工作?先看看这篇 AI 打工仔压榨攻略!
普通网友
博客等级 码龄3年 4493粉丝 309原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值