ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于Django与TensorFlow的个性化音乐推荐系统设计与实现

基于Django与TensorFlow的个性化音乐推荐系统设计与实现 如果今年你抽到的是“基于Django与TensorFlow的个性化音乐推荐系统”这个毕业设计题目那恭喜你这绝对是一个性价比很高的选题。它一头连着Web开发一头连着人工智能与大数据既有爬虫采集又有算法建模还有可视化展示几乎把计算机专业本科阶段的核心技能点都串起来了。更关键的是这套系统做出来之后你的毕业答辩可以从“数据从哪来、模型怎么算、系统怎么跑”三个角度反复讲完全不愁没东西说。我之所以敢这么讲是因为我自己带过不少类似的项目也帮人改过好几版这类系统。今天这篇文章我就把整套系统的设计与实现思路拆开揉碎从爬虫到推荐算法从Django后端到可视化大屏完整讲一遍。无论你是准备拿它当毕业设计还是单纯想练手一个全栈AI项目这篇文章都能让你少走很多弯路。1. 项目整体设计与思路拆解1.1 需求定位这套系统到底要做什么个性化音乐推荐系统表面看就是一个“给用户推荐歌曲”的网站但真正落地的时候你需要拆成三个核心问题来思考。第一个问题是数据从哪来。推荐系统是数据驱动型的应用没有用户行为数据算法再先进也是白搭。真实场景中音乐平台会对用户画像与行为日志进行深度建模但对个人开发者来说拿到这种数据基本不现实。因此用requests爬虫去抓取公开的音乐榜单、歌曲信息、评论数据就成了最合理的方案。公开数据源的数据量足够训练一个演示级别的推荐模型抓取过程本身也是毕业设计的重要工作量。第二个问题是怎么推荐。这里需要引入人工智能算法。TensorFlow是当前最重要的深度学习框架之一在推荐领域有非常成熟的落地案例。我们可以基于用户对歌曲的播放、收藏、跳过等行为训练一个协同过滤模型或者深度神经网络模型让系统能够根据用户历史行为预测他可能喜欢的新歌。第三个问题是怎么呈现。推荐系统不能只跑在命令行里你需要一个可视化的Web平台让用户能注册登录、试听歌曲、查看推荐结果还要让管理员能看到数据统计和推荐效果。这部分用Django来承载非常合适Django的MTV架构、ORM机制和模板引擎能极大提升开发效率。整体来看这个选题覆盖了大数据采集、人工智能建模、Web系统开发三个核心板块工作量饱满但不至于失控非常适合作为本科毕业设计。1.2 技术选型Django、TensorFlow、requests、ECharts各司其职先说我为什么坚持用Django而不是Flask或FastAPI。Django最大的优势是“全家桶”自带Admin后台、用户认证、ORM数据库操作、CSRF防护等功能一个人开发整套系统时效率极高。而且Django的MTV模式对新手来说非常友好MModel负责数据模型TTemplate负责页面模板VView负责业务逻辑。你不需要像做Flask那样自己组装一堆第三方库Django已经帮你安排好了最佳实践。TensorFlow的选择则有两层考虑。一是毕业设计需要体现“人工智能”元素用深度学习框架做推荐模型是门槛较低、展示效果较好的方式。二是TensorFlow的Keras接口非常友好写一个Embedding加Dense的推荐网络只要几十行代码对不擅长算法的同学也很友好。相比PyTorchTensorFlow在部署和可视化工具链上更成熟TensorBoard能直接展示训练曲线放在论文和答辩PPT里效果很好。爬虫端用requests是最稳妥的选择。Scrapy虽然功能更强但学习成本更高而且对一个演示项目来说有点杀鸡用牛刀。requests搭配BeautifulSoup或正则表达式再配合JSON解析完全可以满足需求。更重要的是requests是很多高校《Python网络爬虫》课程的重点内容答辩时分步讲解更占优势。前端可视化我用的是ECharts。Django的模板引擎负责页面骨架ECharts通过Ajax请求后端接口拿JSON数据然后渲染成交互图表。前后端通过接口通信职责清晰后期想拆成前后端分离项目也容易。1.3 数据流向与整体架构这套系统的数据流主线是requests爬虫把外部平台的歌曲信息抓下来 → 写入MySQL或SQLite数据库 → DataFrame加载数据做清洗和特征工程 → TensorFlow读取清洗后的行为数据训练推荐模型 → Django启动时加载模型权重 → 用户点击“获取推荐”时后端把用户特征送入模型推理 → 返回Top N歌曲列表 → ECharts渲染推荐结果和统计图表。这里要特别注意爬虫、数据处理、模型训练、Web服务这四块尽量解耦。我的建议是爬虫脚本单独放一个目录模型训练写成专门的脚本Django项目负责对外提供服务。各模块独立之后训练的时候不依赖Web服务Web服务也不需要每天重新训练模型维护起来轻松很多。2. 数据采集与预处理实战2.1 爬虫目标与合规边界写爬虫之前先把合规红线画清楚。我最常跟学生强调的一句话是爬虫只爬公开数据不碰登录态不做高并发不加逆向破解。网上很多帖子讲爬虫都会提到绕过登录、破解加密参数、模拟JS逆向这些东西这类内容看看就好。一个是技术上容易翻车另一个是法律风险极高。热搜词里那些“因爬虫入狱”“逆向”相关的信息就足以说明问题。做毕业设计我们的目标是拿到足够训练模型的数据不是当黑客。所以我的建议是爬取无需登录即可访问的公开榜单页面比如排行榜、歌单广场这些入口。抓取频率控制在每秒1到2个请求代码里主动设置time.sleep随机延时并且在robots.txt允许的范围内采集。这样的爬虫既是合规的演示时也完全经得起导师追问。2.2 抓取流程requests请求、解析与入库以某个公开音乐榜单为例整个抓取思路是这样的。先构造请求头模拟浏览器访问。很多站点会对不带User-Agent的请求直接拒绝所以请求头一定要伪装到位。然后发送GET请求拿到页面内容如果返回的是JSON接口就解析JSON如果返回的是HTML页面就用BeautifulSoup解析或者用正则表达式提取歌曲名、歌手、专辑、播放链接、封面图等字段。import requests import time import random import pandas as pd headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36, Referer: https://music.example.com/, Accept: application/json, text/plain, */* } def fetch_song_list(page): url fhttps://music.example.com/api/toplist?page{page} resp requests.get(url, headersheaders, timeout10) if resp.status_code ! 200: print(f请求失败{resp.status_code}) return [] data resp.json() songs [] for item in data.get(data, {}).get(list, []): songs.append({ song_id: item.get(id), title: item.get(name), artist: item.get(singer), album: item.get(album), duration: item.get(interval), play_count: item.get(play_cnt), cover_url: item.get(pic), source: 公开榜单 }) return songs all_songs [] for page in range(1, 20): songs fetch_song_list(page) all_songs.extend(songs) time.sleep(random.uniform(1, 3)) df pd.DataFrame(all_songs) df.drop_duplicates(subset[song_id], inplaceTrue) df.to_csv(songs_raw.csv, indexFalse, encodingutf-8-sig)这段代码里我做了几个关键处理。超时设置是必须的不然某个请求卡住会拖死整个爬虫。去重也重要分页抓取很容易因为接口数据交叉出现重复的歌曲ID。最后存成CSV是为了方便后面用pandas做数据清洗实际项目中你也可以直接写入数据库。2.3 数据清洗与特征构造抓到原始数据后不能直接拿去训练模型需要先做清洗。这一步听着没什么技术含量但实际上非常影响推荐效果。首先要处理缺失值。歌曲名、歌手这些核心字段如果为空直接删除该行因为缺失关键信息的歌曲无法用于推荐。播放次数这种数值字段如果为空可以用均值填充或者置为0。其次要处理异常值比如时长超过一小时或者为负数的记录基本都是脏数据。播放量分布通常非常不均衡头部歌曲几百万播放长尾歌曲只有几十次建议做一个log1p变换压缩量纲避免数值差距过大影响模型训练。接着是构造用户行为数据。真实场景里用户对歌曲的操作有播放、收藏、下载、跳过不同行为的权重是不一样的。我在这个项目里构造了一套模拟行为数据参照真实场景设定用户ID、歌曲ID、行为类型、行为时间等字段。行为类型按权重赋值播放记1.0收藏记2.0下载记3.0跳过记-0.5。最终得到一张交互表每行就是一个用户对某首歌的一次操作。import numpy as np df[play_count_log] np.log1p(df[play_count]) df[duration_min] df[duration] / 60 # 过滤异常时长 df df[(df[duration_min] 0.5) (df[duration_min] 20)] # 行为权重映射 behavior_weight {play: 1.0, collect: 2.0, download: 3.0, skip: -0.5} df[rating] df[behavior].map(behavior_weight)特征构造的本质是把原始字符串转成模型能计算的数值。歌曲ID要编码成从0开始的整数索引用户ID同理。这样后面在TensorFlow里做Embedding时才能直接查表。2.4 反爬限流与请求失败处理爬虫写好后最常见的报错就是exceeded retry limit, last status: 429 too many requests。429状态码的意思是请求太频繁被服务器限流了。遇到429不能硬刚越刚越容易被封。我的处理方案是三重退避。第一每次请求之间加随机延时哪怕延时区间是1到2秒也能极大降低触发限流的概率。第二检测到429响应后读取响应头里的Retry-After字段如果服务器明确告诉你等多久就老老实实等到时间再重试。第三增加最大重试次数和指数退避逻辑第一次失败等2秒第二次等4秒第三次等8秒连续失败超过5次就放弃当前请求记入日志。from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type class RateLimitError(Exception): pass retry( stopstop_after_attempt(5), waitwait_exponential(multiplier2, min2, max30), retryretry_if_exception_type((RateLimitError, requests.exceptions.Timeout)) ) def fetch_song_list_with_retry(page): # 省略请求细节... if resp.status_code 429: retry_after int(resp.headers.get(Retry-After, 5)) time.sleep(retry_after) raise RateLimitError(触发限流等待重试) return songs这种带重试和退避的爬虫才是生产环境里能用的爬虫。答辩的时候这一手就能帮你体现工程素养。3. 推荐算法核心TensorFlow建模实战3.1 算法选型为什么用协同过滤加Embedding拿到用户行为数据后推荐算法怎么选我建议用协同过滤思路配合TensorFlow的Embedding层来实现。原因很简单协同过滤不依赖歌曲的内容特征只用“用户和物品的交互矩阵”就能做推荐数据要求低、效果好、可解释性强。具体实现上我们用双塔结构一个塔编码用户一个塔编码歌曲最后通过点积或余弦相似度计算匹配得分。用户塔输入用户ID通过Embedding层转成稠密向量歌曲塔输入歌曲ID也通过Embedding层转成稠密向量。两个向量做内积输出一个得分然后用真实交互数据做监督训练。这种方案其实就是YouTube深度推荐系统和DSSM双塔模型的简化版做毕业设计完全够用而且给后面讲模型演进留了伏笔。3.2 模型结构设计与Keras实现模型结构我用TensorFlow的Keras接口来实现代码量不大但每一层要讲清楚作用。import tensorflow as tf from tensorflow.keras import layers, Model embedding_dim 32 num_users 1000 num_items 5000 user_input layers.Input(shape(1,), nameuser_id) item_input layers.Input(shape(1,), nameitem_id) # Embedding层把离散ID映射成稠密向量 user_embedding layers.Embedding( input_dimnum_users, output_dimembedding_dim, nameuser_embedding )(user_input) item_embedding layers.Embedding( input_dimnum_items, output_dimembedding_dim, nameitem_embedding )(item_input) user_vec layers.Flatten()(user_embedding) item_vec layers.Flatten()(item_embedding) # 点积计算相似度得分 dot_product layers.Dot(axes1)([user_vec, item_vec]) output tf.sigmoid(dot_product) model Model(inputs[user_input, item_input], outputsoutput) model.compile( optimizertf.keras.optimizers.Adam(0.001), lossbinary_crossentropy, metrics[tf.keras.metrics.AUC()] ) model.summary()这里Embedding层的维度我设成了32维。维度太小模型表达能力不足维度太大容易过拟合而且训练变慢。对于本科毕设的数据量32维是性价比较高的选择。训练时还有一个细节就是负样本采样。用户的交互记录里绝大多数都是正样本如果只拿正样本训练模型会学成一个“永远预测1”的废物。所以每条正样本要配两三条负样本从用户没听过的歌里随机抽取生成0标签数据。def generate_negative_samples(user_id, interacted_items, all_items, num_neg3): candidate_items list(set(all_items) - set(interacted_items)) neg_items random.sample(candidate_items, min(num_neg, len(candidate_items))) return [(user_id, item_id, 0) for item_id in neg_items]这样训练数据就是正负样本混合的模型才能真正学会区分喜欢和不喜欢。3.3 训练流程与评估指标训练时把用户ID、歌曲ID作为输入特征把行为权重值二进制化后的0/1作为标签。数据集按照8:1:1切分训练集、验证集、测试集确保同一个用户的行为都被均匀切分避免随机切分导致验证集里全是训练过的物品。评估指标上除了AUC之外我强烈建议加一个推荐领域最常见的指标Top-K命中率。简单说就是模型对用户所有歌曲打分后取分数最高的K首歌曲看用户实际交互过的歌曲有多少首在其中。这个指标最直观答辩时给导师展示也最容易理解。def hit_rate_at_k(model, user_ids, item_ids, labels, k10): hits 0 total 0 for user_id in user_ids.unique(): user_items item_ids[labels[user_ids user_id] 1] if len(user_items) 0: continue # 为该用户所有未交互歌曲打分 scores model.predict([...]) top_k_items pick_top_k(scores, k) hit len(set(top_k_items) set(user_items)) hits hit total min(k, len(user_items)) return hits / total训练过程我会用model.fit加上EarlyStopping回调监控验证集损失连续三个epoch不下降就停止。整套训练在CPU上也能跑数据集小的情况下几分钟就能结束不需要为毕设专门去租GPU服务器。3.4 进一步优化的方向如果时间和能力允许推荐模型还有三个可以改进的方向。第一个方向是从双塔变成三塔加入歌曲的类别特征、歌手特征让模型对歌曲的理解更全面。第二个方向是用注意力机制替代简单的Embedding加内积比如参考DIN模型让模型根据用户历史行为动态计算候选歌曲与历史的相似度这个可以结合热搜里提到的Transformer回归案例来理解本质上都是让特征交互更灵活。第三个方向是图神经网络用LightGCN建模用户和歌曲的二部图关系效果更好但实现复杂度会上一个台阶。我的建议是毕业设计到双塔加负采样这一步已经能达到不错的演示效果。后面这些优化选一个方向做出来并写在“展望”里既显得你有思考深度又不至于把自己拖进大坑。4. Django Web端开发与可视化实现4.1 MTV三层结构如何在项目里落地Django的MTV模式是很多人的理解难点其实完全可以对应到实际代码里说清楚。M层就是models.py里定义的模型类一个模型类对应数据库里一张表字段对应列。T层是templates/目录下的HTML模板负责最终呈现。V层是views.py里的视图函数它接收用户请求、处理业务逻辑、调用模型数据、渲染模板返回页面。在我们这个音乐推荐系统里用户注册、登录、查看推荐、点赞收藏这些操作都能用MTV模式来落地。比如用户点击“获取推荐”按钮后前端发送请求到Django的/recommend路由路由交给对应的视图函数处理视图函数先查数据库拿到当前用户的交互历史然后调用训练好的TensorFlow模型计算Top 10歌曲最后把推荐列表渲染到模板页面。这个过程里没有复杂的架构设计但在答辩时能把逻辑链讲清楚本身就是加分项。4.2 Django项目初始化与数据模型设计项目初始化这块我直接给命令。django-admin startproject music_system创建工程python manage.py startapp music创建App然后在settings.py里注册App并配置数据库。数据模型是整个系统的基础我设计了三张核心表。from django.db import models from django.contrib.auth.models import User class Song(models.Model): song_id models.CharField(max_length32, uniqueTrue, verbose_name歌曲ID) title models.CharField(max_length128, verbose_name歌曲名) artist models.CharField(max_length128, verbose_name歌手) album models.CharField(max_length128, blankTrue, verbose_name专辑) duration models.IntegerField(default0, verbose_name时长(秒)) play_count models.BigIntegerField(default0, verbose_name播放次数) cover_url models.URLField(blankTrue, verbose_name封面) created_at models.DateTimeField(auto_now_addTrue) class Meta: db_table song verbose_name 歌曲信息 class Interaction(models.Model): user models.ForeignKey(User, on_deletemodels.CASCADE, verbose_name用户) song models.ForeignKey(Song, on_deletemodels.CASCADE, verbose_name歌曲) behavior models.CharField(max_length16, verbose_name行为类型) rating models.FloatField(default1.0, verbose_name行为权重) timestamp models.DateTimeField(auto_now_addTrue) class Meta: db_table interaction unique_together (user, song, behavior)这里要注意歌曲表里的song_id对应爬虫抓下来的ID主键依然用Django默认的自增ID两者不冲突。Interaction表是用户和歌曲的关联表推荐模型就是基于这张表来训练的。4.3 推荐接口与模型推理集成模型跑完之后会保存成h5文件或者SavedModel格式Django启动时加载这个文件然后在视图函数里调用模型做推理。import numpy as np from django.shortcuts import render from django.contrib.auth.decorators import login_required from .models import Song, Interaction model None def load_model(): global model if model is None: model tf.keras.models.load_model(model/music_rec_model.h5) return model login_required def recommend(request): user request.user interacted list(Interaction.objects.filter(useruser).values_list(song_id, flatTrue)) # 获取候选歌曲全部歌曲中按播放量取前200首再排除用户听过的 candidates Song.objects.exclude(id__ininteracted).order_by(-play_count)[:200] user_id user.id results [] scores [] for song in candidates: rating model.predict([[user_id], [song.id]])[0][0] scores.append((song.id, rating)) scores.sort(keylambda x: x[1], reverseTrue) top_song_ids [sid for sid, _ in scores[:10]] songs Song.objects.filter(id__intop_song_ids) return render(request, music/recommend.html, {songs: songs})这里有一个性能问题要注意实时对200首候选歌逐一调用predict效率很低。实际开发中更好的方式是批处理预测把200个候选歌曲ID一次性灌入模型一次返回全部评分速度会快很多。这个优化我在实际项目里也踩过坑刚开始逐条预测用户点一次要等好几秒后来改成批量后基本无感。candidate_ids [song.id for song in candidates] batch_user_ids np.array([user_id] * len(candidate_ids)) batch_item_ids np.array(candidate_ids) scores model.predict([batch_user_ids, batch_item_ids]).flatten()4.4 ECharts可视化的两种接入方式可视化的作用不只是好看更是让“个性化推荐”效果直观可见。我用ECharts实现了四个图表歌曲播放量Top10柱状图、用户行为分布饼图、推荐结果命中率折线图、用户听歌时段热力图。ECharts的接入有两种方式。第一种是页面加载时通过Ajax请求后端接口拿JSON数据然后在前端渲染图表。这种方式的优势是数据和页面分离刷图表的前提是后端接口做好了。第二种是把数据直接渲染成Django模板变量嵌入页面再用script标签中的变量初始化图表。这种方式简单直接适合数据量小、不需要动态刷新的场景。我通常推荐第一种方式。后续在答辩现场如果导师想看不同用户的推荐结果或者想看交互数据变化后图表怎么更新Ajax接口配合ECharts的动态数据更新能力会很从容。fetch(/api/statistics, { method: GET, headers: {Content-Type: application/json} }) .then(res res.json()) .then(data { const chart echarts.init(document.getElementById(playChart)); chart.setOption({ title: {text: 播放量Top10歌曲}, xAxis: {type: category, data: data.titles}, yAxis: {type: value}, series: [{type: bar, data: data.play_counts}] }); });4.5 Django静态文件与部署中的常见坑静态文件问题是Django新手最容易踩的坑尤其是配好ECharts后突然发现图表不显示、页面全是404。最典型的场景是本地开发一切正常部署到服务器后style.css、echarts.min.js这些静态资源全部加载失败。遇到这种问题先检查三处配置。settings.py里的DEBUG是否设置为FalseSTATIC_URL是否配置正确STATICFILES_DIRS是否指向了静态文件所在的目录。开发环境用python manage.py runserver时Django会自带静态文件服务但部署阶段DEBUGFalse后这个服务就失效了需要额外配置静态文件处理逻辑。建议直接用python manage.py collectstatic收集所有静态文件再由Web服务器提供服务。热搜里“vscode写img标签 在django的static文件中显示不了”就是这类问题的典型代表。另外强调一件事settings.py里的ALLOWED_HOSTS必须加上服务器域名或IP否则部署后访问会直接报错DisallowedHost。5. 常见问题与排查技巧实录5.1 requests爬虫频繁429被动怎么办热搜词里反复出现exceeded retry limit, last status: 429 too many requests说明很多人都栽在这上面。429的本质是触发了服务端的限流最常见的诱因就是请求频率过高。我的排查顺序是这样的。第一步检查代码里有没有设置请求头UA缺失很容易被反爬策略直接拦截。第二步检查请求频率有的场景隔0.1秒发一个请求不触发429才奇怪。第三步看有没有接入代理池或重试机制如果都没有那一旦触发429就只能干等着。有一个实用的小技巧是抓包看看正常浏览时浏览器发送的请求头字段包括Accept、Accept-Language、Referer等。把这些字段完整复制到requests的headers里爬虫的“拟人度”会大幅提升。加上随机延时和指数退避后429问题基本能解决。如果仍然被限那就不是代码问题了是数据源的风控等级太高建议换个公开数据源。5.2 TensorFlow环境安装与版本冲突TensorFlow安装是很多新手项目启动阶段就卡住的地方。常见报错是Could not load dynamic library cudart64_*.dll或者No module named tensorflow。解决方案是严格匹配Python版本和TensorFlow版本。TensorFlow 2.10及以后版本对Python版本要求比较严格建议使用官方文档指定的Python版本。毕设项目规模根本用不上GPU直接安装CPU版即可安装命令是pip install tensorflow-cpu。如果你同时装了多个Python版本记得检查pip对应的是哪个环境可以通过python -c import sys; print(sys.executable)确认当前Python路径。如果安装时遇到网络问题导致下载中断可以更换国内镜像源pip install tensorflow-cpu -i https://pypi.tuna.tsinghua.edu.cn/simple。装完之后跑一句python -c import tensorflow as tf; print(tf.__version__)立即验证。5.3 推荐结果总是重复或偏向热门歌曲模型上线后最常见的现象是推荐列表怎么刷新都差不多而且全是热门歌曲。原因有两个。第一个原因是候选集太小。如果你的歌曲库只有一两百首歌那无论怎么排推荐结果都逃不出那几首。解决办法是把候选集扩充到上千首或者从不同分类和来源中均衡采样。第二个原因是模型训练不充分或者负采样做得太少导致模型没有学到用户的个性化偏好。检查一下训练日志里的损失曲线如果验证集AUC始终在0.5附近晃说明模型和随机猜测差不多需要调整学习率、增加训练轮次或者补充负样本。冷启动问题也会导致推荐偏向热门。新注册用户没有行为记录模型无法计算他的偏好。我的处理方案是给冷启动用户分配“热门兜底推荐”先推播放量最高的歌曲等用户产生几次点击行为后再切换到个性化推荐。这个逻辑虽然简单但是在答辩时体现系统完整性的重要环节。5.4 前端图表打不开与接口数据格式不匹配ECharts图表一直空白不渲染九成是接口返回的JSON字段名和前端代码里引用的字段名对不上。比如后端返回{song_name: 晴天}而前端写的是data.titles数据取不到图表自然空着。排查方法很简单打开浏览器开发者工具的Network面板查看接口返回的原始JSON结构然后跟前端代码逐字段对应。还有一种情况是后端返回的是一个嵌套结构前端却按扁平结构取值。我建议在Django里把返回数据统一格式化为一个小工具函数确保接口输出的数据结构稳定前端拿到的永远是同一套字段。def response_ok(dataNone, messagesuccess): return JsonResponse({code: 0, message: message, data: data}) def response_error(messageerror): return JsonResponse({code: 1, message: message})5.5 常见问题速查表现象可能原因解决方案爬虫频繁429请求频率过快、缺少请求头添加随机延时伪装浏览器头部指数退避重试TensorFlow安装失败Python版本与TensorFlow不匹配创建虚拟环境安装tensorflow-cpu并验证版本推荐结果全是热门歌候选集太小、模型训练不足扩充候选集增加负样本调整训练参数静态文件404DEBUG设置为False后静态服务失效配置STATIC_ROOT并运行collectstatic图表一直空白JSON字段名不匹配用浏览器开发者工具对照接口返回字段训练时内存溢出一次加载全量数据使用tf.data.Dataset批量读取部署后无法访问ALLOWED_HOSTS未配置在settings.py中添加服务器域名或IP写在最后的个人建议整套系统从零开发到稳定运行我建议你按照“爬虫入库 → 训练模型 → Django展示 → 可视化优化”这条主线推进先把最小闭环跑通再逐步加功能。以我自己的经验来看很多同学喜欢一上来就把界面做得很炫结果数据全是写死的模型也跑不通最后只能靠表演糊弄过去这样反而最容易被答辩导师拆穿。不如先把“爬虫抓数据、TensorFlow训练、Django推荐”这三件事老老实实跑通哪怕界面朴素一点你也能理直气壮地从数据流向讲到算法原理。这个项目后续还有很多可以扩展的空间比如把模拟用户行为换成真实埋点采集、用Redis缓存排名结果、把双塔模型升级成注意力机制版本。任何一个方向做出来都是论文里扎实的一章。最后再分享一个小技巧答辩演示前把推荐的Top10结果和用户听歌历史打出来贴在PPT旁边。导师看到系统确实是根据历史行为给出的推荐而不是随机凑数对你的项目可信度会立刻上一个台阶。毕设这东西做完不难做扎实才值钱。
返回列表