{"id":480,"date":"2025-10-13T19:49:23","date_gmt":"2025-10-13T11:49:23","guid":{"rendered":"https:\/\/blog.keruone.cn\/?p=480"},"modified":"2025-10-13T19:49:23","modified_gmt":"2025-10-13T11:49:23","slug":"hsnet","status":"publish","type":"post","link":"https:\/\/blog.keruone.cn\/index.php\/2025\/10\/13\/hsnet\/","title":{"rendered":"\u7b80\u6613\u795e\u7ecf\u7f51\u7edc\u9884\u6d4b\u4e8c\u9636Hs\u53c2\u6570"},"content":{"rendered":"<h1>\u7b80\u6613\u795e\u7ecf\u7f51\u7edc\u63a8\u9884\u6d4b\u4e8c\u9636Hs\u53c2\u6570<\/h1>\n<p>2025.10.13 Keruone<br \/>\n<\/p>\n<hr \/>\n<h2>\u524d\u8a00<\/h2>\n<p>\u5728\u4eca\u5e74\u7535\u8d5b\u7684G\u9898\u4e2d\uff0c\u4efb\u52a1\u662f<strong>\u5b66\u4e60\u4e00\u4e2a\u4e8c\u9636\u672a\u77e5\u7f51\u7edc\u7684\u53c2\u6570<\/strong>\uff0c\u5e76\u5728\u81ea\u5df1\u7684\u7cfb\u7edf\u4e2d<strong>\u590d\u73b0\u5176\u884c\u4e3a<\/strong>\u3002<\/p>\n<p>\u5f53\u65f6\u7684\u505a\u6cd5\u662f\uff1a\u91c7\u96c6\u8be5\u7f51\u7edc\u5e45\u9891\u548c\u76f8\u9891\u54cd\u5e94\u66f2\u7ebf\u4e2d\u7684\u82e5\u5e72\u6570\u636e\u70b9\uff0c\u901a\u8fc7<strong>SVD\u5206\u89e3\u6c42\u4f2a\u9006<\/strong>\uff0c\u518d\u5229\u7528<strong>\u6700\u5c0f\u4e8c\u4e58\u6cd5<\/strong>\u91cd\u6784\u51fa\u4e8c\u9636\u4f20\u9012\u51fd\u6570 H(s) \u7684<strong>\u4e94\u4e2a\u53c2\u6570<\/strong>\u3002<\/p>\n<p>\u8fd9\u4e00\u65b9\u6cd5\u5728PC\u7aef\u975e\u5e38\u6709\u6548\u2014\u2014\u65e0\u8bba\u662fMATLAB\u8fd8\u662fPython\uff0c\u90fd\u80fd\u9ad8\u6548\u5b8c\u6210\u6240\u9700\u7684\u77e9\u9635\u8fd0\u7b97\u3002\u7136\u800c\uff0c\u4e00\u65e6\u8fc1\u79fb\u5230\u4ee5C\u8bed\u8a00\u4e3a\u4e3b\u7684\u5d4c\u5165\u5f0f\u5e73\u53f0\uff0c\u95ee\u9898\u5c31\u51fa\u73b0\u4e86\uff1a\u867d\u7136\u7406\u8bba\u4e0a\u53ef\u4ee5\u501f\u52a9CMSIS\u7b49\u5e93\u5b9e\u73b0\u57fa\u7840\u77e9\u9635\u64cd\u4f5c\uff0c\u4f46<strong>SVD\u8fd9\u7c7b\u9ad8\u9636\u7ebf\u6027\u4ee3\u6570\u8fd0\u7b97\u5f80\u5f80\u4e0d\u88ab\u652f\u6301<\/strong>\uff1b\u5373\u4fbf\u662f\u50cfK230\u8fd9\u6837\u652f\u6301MicroPython\u7684\u5d4c\u5165\u5f0f\u8bbe\u5907\uff0c\u5176Python\u73af\u5883\u4e5f\u4ec5\u9650\u4e8e\u7b80\u5355\u7684\u77e9\u9635\u8fd0\u7b97\uff0c\u65e0\u6cd5\u76f4\u63a5\u8c03\u7528SVD\u7b49\u590d\u6742\u529f\u80fd\u3002\u56e0\u6b64\uff0c<strong>\u539f\u65b9\u6848\u5728\u8d44\u6e90\u53d7\u9650\u7684\u5e73\u53f0\u4e0a\u96be\u4ee5\u843d\u5730<\/strong>\u3002<\/p>\n<p>\u53d7\u300a\u6df1\u5ea6\u5b66\u4e60\u5165\u95e8\uff1a\u57fa\u4e8ePython\u7684\u7406\u8bba\u4e0e\u5b9e\u73b0\u300b\u548c\u300a\u6df1\u5ea6\u5b66\u4e60\u8fdb\u9636\uff1a\u81ea\u7136\u8bed\u8a00\u5904\u7406\u300b\u7684\u542f\u53d1\uff0c\u6211\u610f\u8bc6\u5230\uff1a<strong>\u4e00\u4e2a\u8f7b\u91cf\u7ea7\u795e\u7ecf\u7f51\u7edc\u7406\u8bba\u4e0a\u5b8c\u5168\u53ef\u4ee5\u66ff\u4ee3\u4e0a\u8ff0\u53c2\u6570\u62df\u5408\u8fc7\u7a0b<\/strong>\u3002<\/p>\n<p>\u66f4\u91cd\u8981\u7684\u662f\uff0c\u8fd9\u4e00\u601d\u8def\u7684\u4ef7\u503c\u8fdc\u4e0d\u6b62\u4e8e\u89e3\u51b3\u4e00\u9053\u7535\u8d5b\u9898\u76ee\u3002\u5728\u672a\u6765\u7684\u8bb8\u591a\u9879\u76ee\u4e2d\uff0c\u6211\u4eec\u53ef\u80fd\u4e00\u65f6\u627e\u4e0d\u5230\u5408\u9002\u7684\u89e3\u6790\u89e3\uff0c\u6216\u8005\u867d\u6709\u7406\u8bba\u65b9\u6848\u5374\u53d7\u9650\u4e8e\u76ee\u6807\u5e73\u53f0\u7684\u8ba1\u7b97\u80fd\u529b\u3002\u800c\u795e\u7ecf\u7f51\u7edc\u63d0\u4f9b\u4e86\u4e00\u79cd\u7075\u6d3b\u7684\u66ff\u4ee3\u8def\u5f84\u2014\u2014<strong>\u8bad\u7ec3\u8fc7\u7a0b\u5b8c\u5168\u53ef\u4ee5\u5728PC\u4e0a\u79bb\u7ebf\u5b8c\u6210<\/strong>\uff0c\u5d4c\u5165\u5f0f\u7aef\u53ea\u9700<strong>\u90e8\u7f72\u8bad\u7ec3\u597d\u7684\u53c2\u6570<\/strong>\uff0c\u5e76\u6267\u884c\u524d\u5411\u63a8\u7406\u6240\u9700\u7684<strong>\u7b80\u5355\u77e9\u9635\u8fd0\u7b97<\/strong>\u5373\u53ef\u3002\u8fd9\u65e2\u89c4\u907f\u4e86\u5e73\u53f0\u9650\u5236\uff0c\u53c8\u4fdd\u7559\u4e86\u6a21\u578b\u7684\u8868\u8fbe\u80fd\u529b\u3002<\/p>\n<h2>&#8212;<\/h2>\n<h2>\u521d\u7248\u793a\u4f8b<\/h2>\n<h3>\u6574\u4f53\u903b\u8f91\u6846\u56fe<\/h3>\n<h3>\u8f93\u5165\u8f93\u51fa\u89c4\u5212<\/h3>\n<p>\u4ee5\u4eca\u5e74\u7535\u8d5bG\u9898\u7684\u201c\u5b66\u4e60\u90e8\u5206\u201d\u4e3a\u4f8b\uff0c<strong>\u8f93\u5165\u8f93\u51fa\u7684\u5408\u7406\u8bbe\u8ba1\u662f\u6574\u4e2a\u65b9\u6848\u6210\u8d25\u7684\u5173\u952e<\/strong>\u3002\u5408\u9002\u7684\u89c4\u5212\u4e0d\u4ec5\u80fd\u663e\u8457\u964d\u4f4e\u6a21\u578b\u590d\u6742\u5ea6\uff0c\u8fd8\u80fd\u63d0\u5347\u6cdb\u5316\u80fd\u529b\u548c\u90e8\u7f72\u6548\u7387\u3002<\/p>\n<p>\u6700\u521d\uff0c\u66fe\u8003\u8651\u8ba9\u795e\u7ecf\u7f51\u7edc\u76f4\u63a5\u66ff\u4ee3\u6574\u4e2a\u672a\u77e5\u7cfb\u7edf\u2014\u2014\u5373\u8f93\u5165\u6fc0\u52b1\u4fe1\u53f7\uff0c\u8f93\u51fa\u54cd\u5e94\u4fe1\u53f7\u3002<strong>\u4f46\u8fd9\u4e00\u601d\u8def\u5b58\u5728\u660e\u663e\u7f3a\u9677<\/strong>\uff1a\u5b83\u8981\u6c42\u8bad\u7ec3\u8fc7\u7a0b\u4e5f\u5fc5\u987b\u5728\u5d4c\u5165\u5f0f\u5e73\u53f0\u4e0a\u5b8c\u6210\uff0c\u4e0d\u4ec5\u53d7\u9650\u4e8e\u7b97\u529b\uff0c\u8fd8\u96be\u4ee5\u4fdd\u8bc1\u5b9e\u65f6\u6027\u4e0e\u8bad\u7ec3\u7a33\u5b9a\u6027\u3002<\/p>\n<p>\u56e0\u6b64\uff0c\u8f6c\u800c\u91c7\u7528<strong>\u53c2\u6570\u56de\u5f52<\/strong>\u7684\u6838\u5fc3\u601d\u8def\uff1a<strong>\u8ba9\u7f51\u7edc\u5b66\u4e60\u5982\u4f55\u4ece\u5e45\u9891\u548c\u76f8\u9891\u54cd\u5e94\u4e2d\u53cd\u63a8\u4e8c\u9636\u4f20\u9012\u51fd\u6570 <span class=\"katex math inline\">H(s)<\/span> \u76845\u4e2a\u53c2\u6570<\/strong>\u3002\u8fd9\u6837\u4e00\u6765\uff0c<strong>\u8bad\u7ec3\u53ea\u9700\u5728PC\u7aef\u79bb\u7ebf\u5b8c\u6210\u4e00\u6b21<\/strong>\uff0c\u5d4c\u5165\u5f0f\u7cfb\u7edf\u5728\u8fd0\u884c\u65f6\u4ec5\u9700\u8c03\u7528\u5df2\u8bad\u7ec3\u597d\u7684\u8f7b\u91cf\u6a21\u578b\u8fdb\u884c\u63a8\u7406\uff0c<strong>\u65e2\u4fdd\u8bc1\u4e86\u5b9e\u65f6\u6027\uff0c\u53c8\u89c4\u907f\u4e86\u5d4c\u5165\u5f0f\u7aef\u65e0\u6cd5\u6267\u884c\u590d\u6742\u8bad\u7ec3\u7684\u95ee\u9898<\/strong>\uff0c\u4ece\u6839\u672c\u4e0a\u89e3\u51b3\u4e86\u5e73\u53f0\u9002\u914d\u96be\u9898\u3002<\/p>\n<p>\u6700\u7ec8\u786e\u5b9a\u7684\u8f93\u5165\u8f93\u51fa\u7ed3\u6784\u5982\u4e0b\uff1a<\/p>\n<ul>\n<li><strong>\u8f93\u5165<\/strong>\uff1a\u57281\u202fkHz\u201310\u202fkHz\u9891\u6bb5\u5185\uff0c\u6309\u5bf9\u6570\u5747\u5300\u95f4\u9694\u9009\u53d632\u4e2a\u9891\u7387\u70b9\uff08\u8be5\u95f4\u9694\u65b9\u5f0f\u53ef\u66f4\u5747\u5300\u8986\u76d6\u9ad8\u4f4e\u9891\u7279\u5f81\uff0c\u907f\u514d\u9ad8\u9891\u4fe1\u606f\u4e22\u5931\uff09\uff0c\u6d4b\u91cf\u672a\u77e5\u7f51\u7edc\u5728\u8fd9\u4e9b\u70b9\u4e0a\u7684\u5e45\u503c\u548c\u76f8\u4f4d\uff1b\u968f\u540e\u5c06\u6bcf\u4e2a\u590d\u6570\u54cd\u5e94\u8f6c\u6362\u4e3a\u5b9e\u90e8\u4e0e\u865a\u90e8\uff0c<strong>\u5b9e\u90e8\u5b58\u5165\u6570\u7ec4\u7684 <code>2*i<\/code> \u4f4d\u7f6e\uff0c\u865a\u90e8\u5b58\u5165 <code>2*i+1<\/code> \u4f4d\u7f6e<\/strong>\uff08\u901a\u8fc7\u56fa\u5b9a\u7d22\u5f15\u89c4\u5219\u786e\u4fdd\u6570\u636e\u6620\u5c04\u7684\u552f\u4e00\u6027\uff0c\u964d\u4f4e\u6a21\u578b\u5b66\u4e60\u96be\u5ea6\uff09\uff0c\u6700\u7ec8\u6784\u6210\u4e00\u4e2a <strong><code>1\u00d764<\/code> \u7684\u8f93\u5165\u5411\u91cf<\/strong>\uff08\u6279\u91cf\u8bad\u7ec3\u65f6\u4e3a <code>N\u00d764<\/code>\uff0c\u6279\u91cf\u6a21\u5f0f\u53ef\u63d0\u5347PC\u7aef\u8bad\u7ec3\u6548\u7387\uff09\u3002<\/p>\n<\/li>\n<li>\n<p><strong>\u8f93\u51fa<\/strong>\uff1a\u4e00\u4e2a <strong><code>1\u00d75<\/code> \u7684\u5411\u91cf<\/strong>\uff08\u6279\u91cf\u65f6\u4e3a <code>N\u00d75<\/code>\uff09\uff0c\u5bf9\u5e94\u4e8c\u9636\u4f20\u9012\u51fd\u6570\u7684\u4e94\u4e2a\u5f85\u8fa8\u8bc6\u53c2\u6570\uff0c\u8bb0\u4e3a <strong><code>[a, b, c, d, e]<\/code><\/strong>\u3002\u4f8b\u5982\uff0c\u53ef\u8bbe<br \/>\n<span class=\"katex math multi-line\">H(s) = \\frac{a s^2 + b s + c}{s^2 + d s + e}<\/span><br \/>\n\u5176\u4e2d<strong>\u5206\u6bcd\u9996\u9879\u7cfb\u6570\u5f52\u4e00\u5316\u4e3a1<\/strong>\uff08\u901a\u8fc7\u5f52\u4e00\u5316\u51cf\u5c11\u53c2\u6570\u5197\u4f59\uff0c\u964d\u4f4e\u6a21\u578b\u6536\u655b\u96be\u5ea6\uff0c\u540c\u65f6\u786e\u4fdd\u53c2\u6570\u8fa8\u8bc6\u7684\u552f\u4e00\u6027\uff09\uff0c\u4ec5\u9700\u8fa8\u8bc6\u8fd9\u4e94\u4e2a\u53c2\u6570\u5373\u53ef\u5b8c\u6574\u63cf\u8ff0\u7cfb\u7edf\u7684\u9891\u57df\u7279\u6027\u3002<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u8fd9\u79cd\u201c\u9891\u57df\u7279\u5f81 \u2192 \u53c2\u6570\u201d\u7684\u6620\u5c04\u65b9\u5f0f\uff0c\u65e2\u4fdd\u7559\u4e86\u660e\u786e\u7684\u7269\u7406\u610f\u4e49\uff08\u6bcf\u4e2a\u8f93\u51fa\u53c2\u6570\u5bf9\u5e94\u4f20\u9012\u51fd\u6570\u7684\u5177\u4f53\u7cfb\u6570\uff0c\u4fbf\u4e8e\u540e\u7eed\u7cfb\u7edf\u590d\u73b0\u4e0e\u9a8c\u8bc1\uff09\uff0c\u53c8\u5929\u7136\u9002\u914d\u8f7b\u91cf\u795e\u7ecf\u7f51\u7edc\u7684\u5efa\u6a21\u80fd\u529b<\/strong>\uff08\u8f93\u5165\u7ef4\u5ea6\u53ef\u63a7\u3001\u8f93\u51fa\u76ee\u6807\u660e\u786e\uff0c\u65e0\u9700\u590d\u6742\u7279\u5f81\u63d0\u53d6\u8fc7\u7a0b\uff09\uff0c\u4e3a\u540e\u7eed\u5728\u8d44\u6e90\u53d7\u9650\u8bbe\u5907\u4e0a\u7684\u90e8\u7f72\u5960\u5b9a\u4e86\u6838\u5fc3\u57fa\u7840\u3002<\/p>\n<hr \/>\n<h3>\u635f\u5931\u51fd\u6570\u89c4\u5212<\/h3>\n<p>\u6839\u636e<strong>\u4efb\u52a1\u6027\u8d28\u4e3a\u8fde\u7eed\u503c\u56de\u5f52\u95ee\u9898<\/strong>\uff0c\u9009\u62e9 MSE \u4f5c\u4e3a\u635f\u5931\u51fd\u6570\uff0c\u5177\u4f53\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-python line-numbers\">class MSELoss:\n    \"\"\"\n    \u5747\u65b9\u8bef\u5dee\u635f\u5931\u5c42\uff08\u7528\u4e8e\u56de\u5f52\uff09\n        L = (1\/N) * sum((y_pred - y_true)^2)\n    \"\"\"\n    def __init__(self):\n        self.params = []\n        self.grads = []\n        self.y_pred = None      # \u9884\u6d4b\u503c\n        self.y_true = None      # \u771f\u5b9e\u503c\n\n    def forward(self, y_pred, y_true):\n        \"\"\"\n        \u6b63\u5411\u4f20\u64ad\uff1a\u8ba1\u7b97 MSE \u635f\u5931\n            args:\n                y_pred: \u7f51\u7edc\u8f93\u51fa\uff0c\u5f62\u72b6 (N, 5)\n                y_true: \u771f\u5b9e\u53c2\u6570\uff0c\u5f62\u72b6 (N, 5)\n            return:\n                loss: \u6807\u91cf\uff08\u5e73\u5747\u635f\u5931\uff09\n        \"\"\"\n        self.y_pred = y_pred\n        self.y_true = y_true\n\n        # \u8ba1\u7b97\u6bcf\u4e2a\u6837\u672c\u7684\u5e73\u65b9\u8bef\u5dee\uff0c\u7136\u540e\u6c42\u5e73\u5747\n        diff = y_pred - y_true\n        loss = np.mean(diff ** 2)  # \u7b49\u4ef7\u4e8e np.sum(diff**2) \/ (N * 5)\n        return loss\n<\/code><\/pre>\n<p><strong>\u4e4b\u6240\u4ee5\u9009\u7528\u5747\u65b9\u8bef\u5dee\uff08MSE\uff09\u4f5c\u4e3a\u635f\u5931\u51fd\u6570\uff0c\u6838\u5fc3\u539f\u56e0\u5728\u4e8e\u672c\u4efb\u52a1\u5c5e\u4e8e\u5178\u578b\u7684\u591a\u8f93\u51fa\u56de\u5f52\u95ee\u9898<\/strong>\uff1a<br \/>\n\u7f51\u7edc\u9700\u8981\u9884\u6d4b\u7684\u662f<strong>\u4e94\u4e2a\u8fde\u7eed\u5b9e\u6570\u53c2\u6570<\/strong>\uff08<code>[a, b, c, d, e]<\/code>\uff09\uff0c\u800c\u975e\u7c7b\u522b\u6807\u7b7e\u3002\u8fd9\u4e9b\u53c2\u6570\u76f4\u63a5\u5bf9\u5e94\u7269\u7406\u7cfb\u7edf\u7684\u4f20\u9012\u51fd\u6570\u7cfb\u6570\uff0c\u5176\u53d6\u503c\u8303\u56f4\u65e0\u56fa\u5b9a\u8fb9\u754c\uff0c\u4e14\u5bf9\u7cbe\u5ea6\u654f\u611f\u3002<\/p>\n<p>\u76f8\u6bd4\u4e4b\u4e0b\uff1a<br \/>\n&#8211; <strong>Softmax + CrossEntropyLoss<\/strong> \u9002\u7528\u4e8e<strong>\u591a\u5206\u7c7b\u4efb\u52a1<\/strong>\uff0c\u8981\u6c42\u8f93\u51fa\u4e3a\u6982\u7387\u5206\u5e03\u4e14\u7c7b\u522b\u4e92\u65a5\uff1b<br \/>\n&#8211; <strong>Sigmoid + Binary CrossEntropy<\/strong> \u9002\u7528\u4e8e<strong>\u4e8c\u5206\u7c7b\u6216\u591a\u6807\u7b7e\u5206\u7c7b<\/strong>\uff0c\u8f93\u51fa\u88ab\u538b\u7f29\u5230 [0,1] \u533a\u95f4\uff1b<br \/>\n&#8211; \u800c <strong>CrossEntropy \u7cfb\u5217\u635f\u5931\u51fd\u6570\u672c\u8d28\u4e0a\u5efa\u6a21\u7684\u662f\u79bb\u6563\u5206\u5e03\u7684\u5dee\u5f02<\/strong>\uff0c\u5e76\u4e0d\u9002\u5408\u8fde\u7eed\u503c\u7684\u7cbe\u786e\u62df\u5408\u3002<\/p>\n<p>\u5728\u56de\u5f52\u573a\u666f\u4e2d\uff0cMSE \u80fd\u76f4\u63a5\u5ea6\u91cf\u9884\u6d4b\u503c\u4e0e\u771f\u5b9e\u503c\u4e4b\u95f4\u7684<strong>\u6b27\u6c0f\u8ddd\u79bb\u5e73\u65b9<\/strong>\uff0c\u5bf9\u8bef\u5dee\u654f\u611f\u3001\u68af\u5ea6\u5e73\u6ed1\uff0c\u4e14\u4e0e\u6700\u5c0f\u4e8c\u4e58\u6cd5\u5728\u7edf\u8ba1\u610f\u4e49\u4e0a\u4e00\u81f4\uff0c<strong>\u5929\u7136\u5951\u5408\u53c2\u6570\u8fa8\u8bc6\u8fd9\u7c7b\u201c\u4ece\u6570\u636e\u62df\u5408\u8fde\u7eed\u53c2\u6570\u201d\u7684\u76ee\u6807<\/strong>\u3002<br \/>\n\u6b64\u5916\uff0cMSE \u7684\u8ba1\u7b97\u7b80\u5355\u3001\u68af\u5ea6\u660e\u786e\uff08<code>\u2202L\/\u2202y_pred = 2*(y_pred - y_true)\/N<\/code>\uff09\uff0c\u4fbf\u4e8e\u5728\u8f7b\u91cf\u7ea7\u7f51\u7edc\u4e2d\u5b9e\u73b0\u53cd\u5411\u4f20\u64ad\uff0c\u4e5f\u5229\u4e8e\u540e\u7eed\u5728\u5d4c\u5165\u5f0f\u7aef\u90e8\u7f72\u65f6\u8fdb\u884c\u7b80\u5316\u6216\u5b9a\u70b9\u5316\u5904\u7406\u3002<\/p>\n<p>\u56e0\u6b64\uff0c<strong>MSE \u662f\u672c\u4efb\u52a1\u4e2d\u6700\u76f4\u63a5\u3001\u5408\u7406\u4e14\u9ad8\u6548\u7684\u9009\u62e9<\/strong>\u3002<\/p>\n<hr \/>\n<h3>\u53c2\u6570\u9884\u5904\u7406<\/h3>\n<h3>\u8bad\u7ec3\u53c2\u6570\u751f\u6210\u4e0e\u89e3\u53c2\u6570\u9884\u5904\u7406<\/h3>\n<p>\u5728\u795e\u7ecf\u7f51\u7edc\u8bad\u7ec3\u4e2d\uff0c<strong>\u8f93\u5165\u7279\u5f81\u4e0e\u8f93\u51fa\u6807\u7b7e\u7684\u5c3a\u5ea6\u548c\u5206\u5e03\u5bf9\u6536\u655b\u901f\u5ea6\u4e0e\u7cbe\u5ea6\u6709\u51b3\u5b9a\u6027\u5f71\u54cd<\/strong>\u3002\u672c\u4efb\u52a1\u4e2d\uff0c\u4e94\u4e2a\u5f85\u8fa8\u8bc6\u53c2\u6570\uff08<code>[a, b, c, d, e]<\/code>\uff09\u7684\u7269\u7406\u91cf\u7eb2\u548c\u6570\u503c\u8303\u56f4\u5dee\u5f02\u6781\u5927\uff1a<br \/>\n&#8211; <code>a<\/code> \u901a\u5e38\u5728 \u00b10.1 \u91cf\u7ea7\uff0c<br \/>\n&#8211; <code>b<\/code> \u7ea6\u4e3a <span class=\"katex math inline\">10^4<\/span>\uff0c<br \/>\n&#8211; \u800c <code>c<\/code>\u3001<code>d<\/code>\u3001<code>e<\/code> \u5219\u53ef\u8fbe <span class=\"katex math inline\">10^8 \\sim 10^{12}<\/span>\u3002<\/p>\n<p>\u82e5\u76f4\u63a5\u4f7f\u7528\u539f\u59cb\u503c\u8bad\u7ec3\uff0c\u7f51\u7edc\u5c06\u96be\u4ee5\u5e73\u8861\u5404\u53c2\u6570\u7684\u68af\u5ea6\u66f4\u65b0\uff0c\u6781\u6613\u9677\u5165\u5c40\u90e8\u6700\u4f18\u6216\u9707\u8361\u3002\u56e0\u6b64\uff0c<strong>\u5fc5\u987b\u5bf9\u8f93\u51fa\u6807\u7b7e\u8fdb\u884c\u5b9a\u5236\u5316\u9884\u5904\u7406<\/strong>\u3002<\/p>\n<p>\u4e3a\u6b64\uff0c\u6211\u4eec\u8bbe\u8ba1\u4e86\u4e00\u5957<strong>\u6df7\u5408\u5c3a\u5ea6\u5f52\u4e00\u5316\u7b56\u7565<\/strong>\uff1a<br \/>\n&#8211; \u5bf9 <code>a<\/code> \u653e\u5927 10 \u500d\u4ee5\u63d0\u5347\u5176\u5728\u635f\u5931\u51fd\u6570\u4e2d\u7684\u6743\u91cd\uff1b<br \/>\n&#8211; \u5bf9 <code>b<\/code> \u7f29\u5c0f 10000 \u500d\u4ee5\u907f\u514d\u5176\u4e3b\u5bfc\u68af\u5ea6\uff1b<br \/>\n&#8211; \u5bf9 <code>c<\/code>\u3001<code>d<\/code>\u3001<code>e<\/code> \u8fd9\u7c7b\u8de8\u8d8a\u591a\u4e2a\u6570\u91cf\u7ea7\u7684\u53c2\u6570\uff0c\u91c7\u7528<strong>\u5e26\u7b26\u53f7\u7684\u5bf9\u6570\u53d8\u6362<\/strong>\uff08<span class=\"katex math inline\">\\text{sign}(x) \\cdot \\log_{10}(|x| + \\epsilon)<\/span>\uff09\uff0c\u5c06\u5176\u538b\u7f29\u5230\u7ebf\u6027\u53ef\u5b66\u4e60\u8303\u56f4\uff1b<br \/>\n&#8211; \u6700\u540e\u5bf9\u6240\u6709\u53d8\u6362\u540e\u7684\u53c2\u6570\u7edf\u4e00\u8fdb\u884c <strong>Z-score \u6807\u51c6\u5316<\/strong>\uff08\u51cf\u5747\u503c\u3001\u9664\u6807\u51c6\u5dee\uff09\uff0c\u4f7f\u8f93\u5165\u7f51\u7edc\u7684\u6807\u7b7e\u8fd1\u4f3c\u670d\u4ece\u6807\u51c6\u6b63\u6001\u5206\u5e03\u3002<\/p>\n<p>\u8fd9\u4e00\u9884\u5904\u7406\u6d41\u7a0b\uff08\u89c1 <code>normalize_params<\/code>\uff09\u4e0d\u4ec5\u663e\u8457\u63d0\u5347\u4e86\u8bad\u7ec3\u7a33\u5b9a\u6027\uff0c\u8fd8\u4f7f\u5f97\u7f51\u7edc\u80fd\u66f4\u5747\u8861\u5730\u5b66\u4e60\u6bcf\u4e2a\u53c2\u6570\u7684\u6620\u5c04\u5173\u7cfb\u3002\u66f4\u91cd\u8981\u7684\u662f\uff0c\u6211\u4eec\u5b8c\u6574\u4fdd\u7559\u4e86\u53cd\u53d8\u6362\u6240\u9700\u7684\u6240\u6709\u7edf\u8ba1\u4fe1\u606f\uff08\u7f29\u653e\u56e0\u5b50\u3001\u5747\u503c\u3001\u6807\u51c6\u5dee\u3001\u662f\u5426\u5bf9\u6570\u5316\u7b49\uff09\uff0c\u901a\u8fc7 <code>denormalize_params<\/code> \u53ef<strong>\u65e0\u635f\u8fd8\u539f\u539f\u59cb\u7269\u7406\u53c2\u6570<\/strong>\u3002<\/p>\n<p>\u5176\u4e2d\u4ee3\u7801\u4e3b\u8981\u4e3a4\u4e2a\u51fd\u6570\uff1a<br \/>\n&#8211; \u6839\u636e<strong>\u53c2\u6570<\/strong>\u751f\u6210<strong>\u5e45\u9891\u76f8\u9891\u6570\u636e<\/strong><br \/>\n&#8211; \u5bf9<strong>\u53c2\u6570<\/strong>\u8fdb\u884c<strong>\u9884\u5904\u7406<\/strong>\u4f5c\u4e3a\u795e\u7ecf\u7f51\u7edc\u8bad\u7ec3\u7684<strong>\u8f93\u51fa\u6807\u7b7e<\/strong>\u7684\u51fd\u6570<br \/>\n&#8211; \u5bf9<strong>\u795e\u7ecf\u7f51\u7edc\u8f93\u51fa<\/strong>\u8fdb\u884c<strong>\u53cd\u5904\u7406<\/strong>\u5f97\u5230<strong>\u5b9e\u9645\u53c2\u6570<\/strong>\u7684\u51fd\u6570<br \/>\n&#8211; \u4e3a\u795e\u7ecf\u7f51\u7edc<strong>\u52a0\u8f7d\u8bad\u7ec3\u6570\u636e<\/strong>\u7684<code>load_data<\/code>\u51fd\u6570<\/p>\n<p>\u5177\u4f53\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-python line-numbers\">import numpy as np\nimport matplotlib.pyplot as plt\n\ndef generate_frequency_response(a, b, c, d, e, f_min=10e3, f_max=100e3, n_freq=32):\n    \"\"\"\u6839\u636e\u4f20\u9012\u51fd\u6570\u53c2\u6570\u751f\u6210\u9891\u7387\u54cd\u5e94\uff08\u590d\u6570\u5f62\u5f0f\uff09\"\"\"\n    f = np.logspace(np.log10(f_min), np.log10(f_max), n_freq)\n    w = 2 * np.pi * f\n    s = 1j * w\n\n    numerator = a * s**2 + b * s + c\n    denominator = s**2 + d * s + e\n    H = numerator \/ denominator\n\n    return f, H\n\ndef normalize_params(Y):\n    \"\"\"\n    \u5b9a\u5236\u5316\u53c2\u6570\u5f52\u4e00\u5316:\n    - a: \u653e\u592710\u500d\u540e\u76f4\u63a5z-score\n    - b: \u7f29\u5c0f10000\u500d\u540e\u76f4\u63a5z-score\n    - c\/d\/e: \u5e26\u7b26\u53f7log10\u53d8\u6362\u540ez-score\n    \"\"\"\n    Y_processed = Y.copy()\n    # \u6807\u8bb0\u9700\u8981log\u9006\u53d8\u6362\u7684\u53c2\u6570\n    is_logged = [False, False, True, True, True]  # [a, b, c, d, e]\n    # \u5b9a\u4e49\u7f29\u653e\u7cfb\u6570\n    a_scale = 10\n    b_scale = 10000\n\n    # \u5904\u7406a: \u653e\u592710\u500d\n    Y_processed[:, 0] *= a_scale\n\n    # \u5904\u7406b: \u7f29\u5c0f10000\u500d\n    Y_processed[:, 1] \/= b_scale\n\n    # \u5904\u7406c\/d\/e: \u5e26\u7b26\u53f7log10\u53d8\u6362\n    for i in [2, 3, 4]:\n        sign = np.sign(Y_processed[:, i])\n        abs_log = np.log10(np.abs(Y_processed[:, i]) + 1e-6)  # \u907f\u514dlog(0)\n        Y_processed[:, i] = sign * abs_log\n\n    # \u7edf\u4e00z-score\u5f52\u4e00\u5316\n    mean = np.mean(Y_processed, axis=0)\n    std = np.std(Y_processed, axis=0)\n    Y_norm = (Y_processed - mean) \/ (std + 1e-8)\n\n    # \u5b58\u50a8\u53cd\u5f52\u4e00\u5316\u6240\u9700\u4fe1\u606f\n    stats = {\n        \"mean\": mean,\n        \"std\": std,\n        \"is_logged\": is_logged,\n        \"a_scale\": a_scale,\n        \"b_scale\": b_scale\n    }\n\n    return Y_norm, stats\n\ndef denormalize_params(Y_norm, stats):\n    \"\"\"\u53cd\u5f52\u4e00\u5316\uff0c\u6062\u590d\u539f\u59cb\u53c2\u6570\u5c3a\u5ea6\"\"\"\n    # z-score\u9006\u53d8\u6362\n    Y_processed = Y_norm * stats[\"std\"] + stats[\"mean\"]\n    Y = Y_processed.copy()\n\n    # \u5bf9log\u53d8\u6362\u53c2\u6570\u6267\u884c\u9006\u53d8\u6362\n    for i in range(5):\n        if stats[\"is_logged\"][i]:\n            sign = np.sign(Y_processed[:, i])\n            abs_exp = 10 ** np.abs(Y_processed[:, i])\n            Y[:, i] = sign * abs_exp\n\n    # \u8fd8\u539fa\u7684\u5c3a\u5ea6\n    Y[:, 0] \/= stats[\"a_scale\"]\n\n    # \u8fd8\u539fb\u7684\u5c3a\u5ea6\n    Y[:, 1] *= stats[\"b_scale\"]\n\n    return Y\n\ndef load_data(seed=1984, n_samples=100):\n    np.random.seed(seed)\n\n    f_min, f_max = 10e3, 100e3  # Hz\n    N_freq = 32\n    f = np.logspace(np.log10(f_min), np.log10(f_max), N_freq)\n    w = 2 * np.pi * f\n\n    X = []\n    Y = []\n\n    for _ in range(n_samples):\n        # \u751f\u6210\u6781\u70b9\u53c2\u6570\n        wn = np.random.uniform(2*np.pi*5e3, 2*np.pi*200e3)\n        zeta = np.random.lognormal(mean=np.log(0.2), sigma=1.0)\n        zeta = np.clip(zeta, 0.05, 1.5)\n        K = np.random.lognormal(mean=np.log(1.0), sigma=1.0)\n        K = np.clip(K, 0.01, 100)\n\n        # \u751f\u6210\u5206\u5b50\u53c2\u6570\n        a = np.random.normal(0, 0.1)  # \u539f\u59cb\u5c3a\u5ea6\u2248\u00b10.1\n        b = np.abs(np.random.normal(0, 1e4))  # \u539f\u59cb\u5c3a\u5ea6\u22481e4\n        c = K * wn**2  # \u539f\u59cb\u5c3a\u5ea6\u22481e8~1e12\n\n        # \u751f\u6210\u5206\u6bcd\u53c2\u6570\n        d = 2 * zeta * wn  # \u539f\u59cb\u5c3a\u5ea6\u22481e4~1e6\n        e = wn**2  # \u539f\u59cb\u5c3a\u5ea6\u22481e8~1e12\n\n        # \u8ba1\u7b97\u9891\u7387\u54cd\u5e94\n        s = 1j * w\n        H = (a * s**2 + b * s + c) \/ (s**2 + d * s + e)\n        x = np.concatenate([H.real, H.imag])\n\n        X.append(x)\n        Y.append([a, b, c, d, e])\n\n    X = np.array(X)\n    Y = np.array(Y)\n\n    Y_norm, stats = normalize_params(Y)\n    # return X, Y_norm, stats, Y\n    return X, Y_norm, stats\n<\/code><\/pre>\n<hr \/>\n<h3>\u5177\u4f53\u7f51\u7edc HsNet<\/h3>\n<p>\u793a\u610f\u56fe\u5982\u56fe<br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/10\/\u7f51\u7edc\u67b6\u6784\u793a\u610f\u56fe.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/10\/\u7f51\u7edc\u67b6\u6784\u793a\u610f\u56fe.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\u7f51\u7edc\u67b6\u6784\u793a\u610f\u56fe\" \/><\/div><br \/>\n\u7f51\u7edc\u4e3b\u4f53<\/p>\n<pre><code class=\"language-python line-numbers\">import os\nimport sys\n# \u5c06\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u5207\u6362\u5230\u8be5\u811a\u672c\u6240\u5728\u7684\u76ee\u5f55\nscript_dir = os.path.dirname(os.path.abspath(__file__))\nos.chdir(script_dir)\nsys.path.append('..')  \nimport numpy as np\nfrom common.layers import Affine, Sigmoid, MSELoss, ReLU\n\nclass HsNet:\n    def __init__(self, input_size, hidden_size, output_size):\n        I, H, O = input_size, hidden_size, output_size\n\n        # He \u521d\u59cb\u5316\uff08\u9002\u5408 ReLU\uff09\n        W1 = np.random.randn(I, H) * np.sqrt(2.0 \/ I)\n        b1 = np.zeros(H)\n        W2 = np.random.randn(H, H) * np.sqrt(2.0 \/ H)  # \u7b2c\u4e8c\u9690\u85cf\u5c42\n        b2 = np.zeros(H)\n        W3 = np.random.randn(H, H) * np.sqrt(2.0 \/ H)  # \u7b2c\u4e8c\u9690\u85cf\u5c42\n        b3 = np.zeros(H)\n        W4 = np.random.randn(H, O) * np.sqrt(2.0 \/ H)\n        b4 = np.zeros(O)\n\n        self.layers = [\n            Affine(W1, b1),\n            ReLU(),\n            Affine(W2, b2),\n            ReLU(),\n            Affine(W3, b3),\n            ReLU(),\n            Affine(W4, b4)\n        ]\n        self.loss_layer = MSELoss()\n\n        self.params = []\n        self.grads = []\n        for layer in self.layers:\n            self.params += layer.params\n            self.grads += layer.grads\n\n    def predict(self, x):\n        for layer in self.layers:\n            x = layer.forward(x)\n        return x\n    def forward(self, x, t):\n        x = self.predict(x)\n        loss = self.loss_layer.forward(x,t)\n        return loss\n    def backward(self, dout = 1):\n        dout = self.loss_layer.backward(dout)\n        for layer in reversed(self.layers):\n            dout = layer.backward(dout)\n        return dout\n\n<\/code><\/pre>\n<p>\u53c2\u6570\u8bfb\u53d6\u548c\u4fdd\u5b58\uff0c\u4f5c\u4e3a\u8be5\u5bf9\u8c61\u7684\u7c7b\u51fd\u6570\u3002<\/p>\n<pre><code class=\"language-python line-numbers\">    def save_parameters(self, file_path):\n        \"\"\"\n        \u4fdd\u5b58\u6a21\u578b\u53c2\u6570\u5230\u6587\u4ef6\n\n        \u53c2\u6570:\n            file_path: \u4fdd\u5b58\u53c2\u6570\u7684\u6587\u4ef6\u8def\u5f84\uff08\u901a\u5e38\u4f7f\u7528.npz\u6269\u5c55\u540d\uff09\n        \"\"\"\n        # \u521b\u5efa\u4e00\u4e2a\u5b57\u5178\u6765\u5b58\u50a8\u6240\u6709\u53c2\u6570\n        params_dict = {f'param_{i}': param for i, param in enumerate(self.params)}\n\n        # \u4fdd\u5b58\u53c2\u6570\n        np.savez(file_path, **params_dict)\n        print(f\"\u53c2\u6570\u5df2\u4fdd\u5b58\u5230 {file_path}\")\n\n    def load_parameters(self, file_path):\n        \"\"\"\n        \u4ece\u6587\u4ef6\u52a0\u8f7d\u6a21\u578b\u53c2\u6570\n\n        \u53c2\u6570:\n            file_path: \u52a0\u8f7d\u53c2\u6570\u7684\u6587\u4ef6\u8def\u5f84\n        \"\"\"\n        if not os.path.exists(file_path):\n            raise FileNotFoundError(f\"\u53c2\u6570\u6587\u4ef6 {file_path} \u4e0d\u5b58\u5728\")\n\n        # \u52a0\u8f7d\u53c2\u6570\n        loaded_data = np.load(file_path)\n\n        # \u68c0\u67e5\u52a0\u8f7d\u7684\u53c2\u6570\u6570\u91cf\u662f\u5426\u4e0e\u6a21\u578b\u9884\u671f\u7684\u4e00\u81f4\n        if len(loaded_data.files) != len(self.params):\n            raise ValueError(f\"\u53c2\u6570\u6570\u91cf\u4e0d\u5339\u914d: \u9884\u671f {len(self.params)} \u4e2a, \u4f46\u6587\u4ef6\u4e2d\u6709 {len(loaded_data.files)} \u4e2a\")\n\n        # \u5c06\u52a0\u8f7d\u7684\u53c2\u6570\u8d4b\u503c\u7ed9\u6a21\u578b\n        for i in range(len(self.params)):\n            self.params[i] = loaded_data[f'param_{i}']\n\n            # \u540c\u65f6\u66f4\u65b0\u5bf9\u5e94\u5c42\u7684\u53c2\u6570\uff08\u56e0\u4e3aparams\u662f\u5c42\u53c2\u6570\u7684\u5f15\u7528\uff09\n            # \u627e\u5230\u5bf9\u5e94\u7684\u5c42\u548c\u53c2\u6570\u7d22\u5f15\n            param_idx = 0\n            for layer in self.layers:\n                if hasattr(layer, 'params'):\n                    for j in range(len(layer.params)):\n                        if param_idx == i:\n                            layer.params[j] = self.params[i]\n                            break\n                        param_idx += 1\n                    if param_idx &gt; i:\n                        break\n\n        print(f\"\u5df2\u4ece {file_path} \u52a0\u8f7d\u53c2\u6570\")\n<\/code><\/pre>\n<h3>\u8bad\u7ec3\u90e8\u5206\u53ca\u5bf9\u6bd4\u6f14\u793a\u4ee3\u7801<\/h3>\n<pre><code class=\"language-python line-numbers\">import os\nimport sys\nscript_dir = os.path.dirname(os.path.abspath(__file__))\nos.chdir(script_dir)\nsys.path.append('..')\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# -------------------------- 1. \u6838\u5fc3\u914d\u7f6e\uff1a\u7edf\u4e00\u5b58\u50a8\u76ee\u5f55 --------------------------\n# \u6839\u76ee\u5f55\u540d\u79f0\uff08\u53ef\u81ea\u5b9a\u4e49\uff0c\u5982\"hsnet_results_2024\"\uff09\nROOT_SAVE_DIR = \"hsnet_training_results\"\n# \u5b50\u76ee\u5f55\u5212\u5206\uff08\u5206\u7c7b\u5b58\u50a8\u4e0d\u540c\u7c7b\u578b\u6587\u4ef6\uff09\nPARAM_SAVE_DIR = os.path.join(ROOT_SAVE_DIR, \"model_params\")    # \u6a21\u578b\u53c2\u6570\nIMAGE_SAVE_DIR = os.path.join(ROOT_SAVE_DIR, \"plots\")           # \u56fe\u7247\nLOSS_SAVE_DIR = os.path.join(ROOT_SAVE_DIR, \"loss_data\")        # \u635f\u5931\u6570\u636e\n\n# \u81ea\u52a8\u521b\u5efa\u6240\u6709\u76ee\u5f55\uff08\u4e0d\u5b58\u5728\u5219\u521b\u5efa\uff0c\u907f\u514d\u62a5\u9519\uff09\nfor dir_path in [ROOT_SAVE_DIR, PARAM_SAVE_DIR, IMAGE_SAVE_DIR, LOSS_SAVE_DIR]:\n    if not os.path.exists(dir_path):\n        os.makedirs(dir_path)\n        print(f\"\u521b\u5efa\u76ee\u5f55: {dir_path}\")\n\n# -------------------------- 2. \u57fa\u7840\u5bfc\u5165\u4e0e\u8def\u5f84\u914d\u7f6e --------------------------\n# \u5bfc\u5165\u6a21\u5757\nfrom HsNet import HsNet\nfrom dataset import ch01HsGenerate  # \u786e\u4fdd\u8fd4\u56de (X, Y_norm, stats)\nfrom common.optimizer import Adam, AdamW, ReduceLROnPlateau\n\n# -------------------------- 3. \u8bad\u7ec3\u53c2\u6570\u8bbe\u5b9a --------------------------\nmax_epoch = 2000\nbatch_size = 32\nhidden_size = 256          \nlearning_rate = 0.001      \n# \u7edf\u4e00\u6587\u4ef6\u8def\u5f84\uff08\u5173\u8054\u5230\u5b50\u76ee\u5f55\uff09\nparam_save_path = os.path.join(PARAM_SAVE_DIR, \"hsnet_trained_params.npz\")  # \u53c2\u6570\u6587\u4ef6\nloss_save_path = os.path.join(LOSS_SAVE_DIR, \"training_loss.npz\")            # \u635f\u5931\u6570\u636e\u6587\u4ef6\n# \u56fe\u7247\u8def\u5f84\uff08\u540e\u7eed\u7ed8\u56fe\u65f6\u4f7f\u7528\uff09\nloss_plot_path = os.path.join(IMAGE_SAVE_DIR, \"loss_curve.png\")\npred_true_plot_path = os.path.join(IMAGE_SAVE_DIR, \"pred_vs_true.png\")\nfreq_response_plot_path = os.path.join(IMAGE_SAVE_DIR, \"frequency_response.png\")\n\n# -------------------------- 4. \u6570\u636e\u52a0\u8f7d --------------------------\ndata = ch01HsGenerate.load_data(seed = None,n_samples=5000)\nif len(data) == 3:\n    X, Y_norm, stats = data\nelse:\n    X, Y_norm = data\n    stats = None  \n\nx_orig = X.copy()\nt_orig = Y_norm.copy()\n\n# \u6570\u636e\u7ef4\u5ea6\u6821\u9a8c\ndata_size, input_size = X.shape\n_, output_size = Y_norm.shape\nassert output_size == 5, \"\u8f93\u51fa\u5fc5\u987b\u662f5\u7ef4\u53c2\u6570\uff01\"\niters = data_size \/\/ batch_size\ntotal_loss = 0\nloss_count = 0\nloss_list = []  # \u5b58\u50a8\u6240\u6709\u5e73\u5747\u635f\u5931\uff08\u540e\u7eed\u4fdd\u5b58\uff09\n\n# -------------------------- 5. \u6a21\u578b\u521d\u59cb\u5316\u4e0e\u9884\u8bad\u7ec3\u52a0\u8f7d --------------------------\nmodel = HsNet(input_size, hidden_size, output_size)\noptimizer = AdamW(lr=learning_rate, weight_decay = 0.01)\nscheduler = ReduceLROnPlateau(optimizer, mode='min', factor=0.5, patience=100, verbose=True)\n\n# \u52a0\u8f7d\u9884\u8bad\u7ec3\u6a21\u578b\uff08\u53ef\u9009\uff09\nload_pretrained = False\nif os.path.exists(param_save_path):\n    choice = input(f\"\u53d1\u73b0\u9884\u8bad\u7ec3\u53c2\u6570\u6587\u4ef6 {param_save_path}\\n\u662f\u5426\u52a0\u8f7d\u5e76\u8df3\u8fc7\u8bad\u7ec3\uff1f(y\/n): \").lower()\n    if choice == \"y\":\n        model.load_parameters(param_save_path)\n        load_pretrained = True\n        # \u82e5\u5b58\u5728\u4fdd\u5b58\u7684\u635f\u5931\u6570\u636e\uff0c\u52a0\u8f7d\u5230loss_list\uff08\u7528\u4e8e\u7ed8\u56fe\uff09\n        if os.path.exists(loss_save_path):\n            loss_list = np.load(loss_save_path)[\"loss_list\"].tolist()\n            print(f\"\u5df2\u52a0\u8f7d\u5386\u53f2\u635f\u5931\u6570\u636e\uff08\u5171{len(loss_list)}\u4e2a\u8bb0\u5f55\u70b9\uff09\")\n\n# -------------------------- 6. \u8bad\u7ec3\u5faa\u73af\uff08\u4ec5\u5f53\u672a\u52a0\u8f7d\u9884\u8bad\u7ec3\u65f6\u6267\u884c\uff09 --------------------------\nif not load_pretrained:\n    print(\"\\n\u5f00\u59cb\u8bad\u7ec3...\")\nif not load_pretrained:\n    print(\"\\n\u5f00\u59cb\u8bad\u7ec3\uff08\u6bcf\u6b21epoch\u52a8\u6001\u751f\u6210\u65b0\u6570\u636e\uff09...\")\n    total_loss = 0\n    loss_count = 0\n\n    for epoch in range(max_epoch):\n        # \u2705 \u5173\u952e\u4fee\u6539\uff1a\u6bcf\u6b21epoch\u52a8\u6001\u751f\u6210\u65b0\u8bad\u7ec3\u6570\u636e\n        train_data = ch01HsGenerate.load_data(seed=None, n_samples=5000)  # seed=None \u786e\u4fdd\u968f\u673a\u6027\n        if len(train_data) == 3:\n            X, Y_norm, _ = train_data  # \u5ffd\u7565stats\uff0c\u8bad\u7ec3\u7528\u5f52\u4e00\u5316\u6570\u636e\u5373\u53ef\n        else:\n            X, Y_norm = train_data\n\n        data_size = X.shape[0]\n        iters = data_size \/\/ batch_size\n\n        # \u968f\u673a\u6253\u4e71\uff08\u867d\u7136load_data\u5df2\u968f\u673a\uff0c\u4f46\u518d\u6253\u4e71\u66f4\u7a33\u59a5\uff09\n        idx = np.random.permutation(data_size)\n        X_shuffled = X[idx]\n        Y_shuffled = Y_norm[idx]\n\n        epoch_loss = 0\n        for iter in range(iters):\n            batch_x = X_shuffled[iter * batch_size : (iter + 1) * batch_size]\n            batch_t = Y_shuffled[iter * batch_size : (iter + 1) * batch_size]\n\n            loss = model.forward(batch_x, batch_t)\n            model.backward()\n            optimizer.update(model.params, model.grads)\n\n            epoch_loss += loss\n            total_loss += loss\n            loss_count += 1\n\n            if loss_count % 10 == 0:\n                avg_loss = total_loss \/ loss_count\n                loss_list.append(avg_loss)\n                total_loss = 0\n                loss_count = 0\n                print(f'| epoch {epoch + 1:4d} | iter {iter + 1:3d}\/{iters} | loss {avg_loss:.6f}')\n\n        # \u6bcf\u4e2aepoch\u7ed3\u675f\u540e\u66f4\u65b0\u5b66\u4e60\u7387\uff08\u57fa\u4e8eepoch\u5e73\u5747\u635f\u5931\uff09\n        avg_epoch_loss = epoch_loss \/ iters\n        scheduler.step(avg_epoch_loss)\n\n\n    # -------------------------- 6.1 \u8bad\u7ec3\u540e\u4fdd\u5b58\uff1a\u53c2\u6570 + \u635f\u5931 --------------------------\n    # \u4fdd\u5b58\u6a21\u578b\u53c2\u6570\n    model.save_parameters(param_save_path)\n    # \u4fdd\u5b58\u635f\u5931\u6570\u636e\uff08\u7528npz\u683c\u5f0f\uff0c\u65b9\u4fbf\u540e\u7eed\u52a0\u8f7d\uff09\n    np.savez(loss_save_path, loss_list=np.array(loss_list))\n    print(f\"\\n\u635f\u5931\u6570\u636e\u5df2\u4fdd\u5b58\u5230: {loss_save_path}\")\n    plt.figure(figsize=(10, 4))\n    plt.plot(loss_list, label='Training Loss (Avg per 10 Iters)', color='purple', linewidth=1.5)\n    plt.xlabel('Iteration Groups (\u00d710 Iters)', fontsize=10)\n    plt.ylabel('MSE Loss', fontsize=10)\n    plt.title('HsNet Training Loss Curve', fontsize=12, fontweight='bold')\n    plt.grid(True, linestyle='--', alpha=0.7)\n    plt.legend(fontsize=9)\n    plt.tight_layout()  # \u81ea\u52a8\u8c03\u6574\u5e03\u5c40\uff0c\u907f\u514d\u6807\u7b7e\u88ab\u622a\u65ad\n    plt.savefig(loss_plot_path, dpi=300, bbox_inches='tight')  # dpi=300\u786e\u4fdd\u9ad8\u6e05\n    plt.close()  # \u5173\u95ed\u753b\u5e03\uff0c\u907f\u514d\u5185\u5b58\u5360\u7528\n    print(f\"\u635f\u5931\u66f2\u7ebf\u5df2\u4fdd\u5b58\u5230: {loss_plot_path}\")\n\n# -------------------------- 7. \u7ed3\u679c\u53ef\u89c6\u5316\uff1a\u7ed8\u56fe\u5e76\u4fdd\u5b58\u5230\u56fe\u7247\u76ee\u5f55 --------------------------\nprint(\"\\n\u5f00\u59cb\u751f\u6210\u53ef\u89c6\u5316\u7ed3\u679c...\")\n\n# -------------------------- 7.1 1. \u635f\u5931\u66f2\u7ebf\uff08\u4fdd\u5b58\u5230IMAGE_SAVE_DIR\uff09 --------------------------\n\n\n# -------------------------- 7.2 2. \u9884\u6d4b\u503c vs \u771f\u5b9e\u503c\uff085\u4e2a\u5b50\u56fe\uff0c\u4fdd\u5b58\u5230IMAGE_SAVE_DIR\uff09 --------------------------\n# \u6a21\u578b\u9884\u6d4b\uff08\u7528\u539f\u59cb\u6570\u636e\uff09\nY_pred_norm = model.predict(x_orig)  \n# \u53cd\u5f52\u4e00\u5316\u5230\u7269\u7406\u53c2\u6570\uff08\u82e5\u6709stats\uff09\nif stats is not None:\n    Y_pred = ch01HsGenerate.denormalize_params(Y_pred_norm, stats)\n    Y_true = ch01HsGenerate.denormalize_params(t_orig, stats)\nelse:\n    Y_pred = Y_pred_norm\n    Y_true = t_orig\n\n# \u53c2\u6570\u540d\u79f0\uff08\u4e0e\u4f60\u76845\u7ef4\u8f93\u51fa\u5bf9\u5e94\uff09\nparam_names = ['b\u2080 (num s\u00b2)', 'b\u2081 (num s)', 'b\u2082 (num const)', 'a\u2081 (den s)', 'a\u2082 (den const)']\n\nplt.figure(figsize=(15, 10))\nfor i in range(5):\n    plt.subplot(2, 3, i + 1)  # 2\u884c3\u5217\u5e03\u5c40\uff0c\u7a7a\u51fa\u7b2c6\u4e2a\u5b50\u56fe\n\n    # \u63d0\u53d6\u5f53\u524d\u53c2\u6570\u7684\u771f\u5b9e\u503c\u548c\u9884\u6d4b\u503c\n    true_vals = Y_true[:, i]\n    pred_vals = Y_pred[:, i]\n\n    # \u7ed8\u5236\u6563\u70b9\u56fe\n    plt.scatter(true_vals, pred_vals, alpha=0.6, s=20, color='orange', label='Predicted', zorder=2)\n    plt.scatter(true_vals, true_vals, alpha=0.4, s=10, color='blue', marker='x', label='True (Ref)', zorder=1)\n\n    # \u7ed8\u5236\u7406\u60f3\u53c2\u8003\u7ebf\uff08y=x\uff09\n    min_val = min(true_vals.min(), pred_vals.min()) * 0.95  # \u7559\u5c11\u91cf\u8fb9\u8ddd\n    max_val = max(true_vals.max(), pred_vals.max()) * 1.05\n    plt.plot([min_val, max_val], [min_val, max_val], 'k--', linewidth=1.2, label='Ideal: Pred=True', zorder=3)\n\n    # \u6807\u7b7e\u4e0e\u683c\u5f0f\n    plt.xlabel('True Value', fontsize=9)\n    plt.ylabel('Predicted Value', fontsize=9)\n    plt.title(f'Parameter: {param_names[i]}', fontsize=10, fontweight='bold')\n    plt.grid(True, linestyle='--', alpha=0.5)\n    plt.legend(fontsize=8)\n\n# \u5220\u9664\u7b2c6\u4e2a\u7a7a\u7684\u5b50\u56fe\uff082\u884c3\u5217\uff0c\u6700\u540e\u4e00\u4e2a\u4f4d\u7f6e\uff09\nplt.delaxes(plt.subplot(2, 3, 6))\nplt.tight_layout()\nplt.savefig(pred_true_plot_path, dpi=300, bbox_inches='tight')\nplt.close()\nprint(f\"\u9884\u6d4bvs\u771f\u5b9e\u503c\u56fe\u5df2\u4fdd\u5b58\u5230: {pred_true_plot_path}\")\n\n# -------------------------- 7.3 3. \u5e45\u9891\/\u76f8\u9891\u54cd\u5e94\u5bf9\u6bd4\uff08\u4fdd\u5b58\u5230IMAGE_SAVE_DIR\uff09 --------------------------\n# \u9891\u7387\u8bbe\u7f6e\uff08\u4e0e\u6570\u636e\u751f\u6210\u903b\u8f91\u4e00\u81f4\uff09\nf_min, f_max = 10e3, 100e3  # Hz\nN_freq = 32\nf = np.logspace(np.log10(f_min), np.log10(f_max), N_freq)  # \u5bf9\u6570\u5747\u5206\u9891\u7387\nw = 2 * np.pi * f  # \u89d2\u9891\u7387\n\n# \u968f\u673a\u90093\u4e2a\u6837\u672c\u8fdb\u884c\u5bf9\u6bd4\uff08\u56fa\u5b9aseed\u786e\u4fdd\u7ed3\u679c\u53ef\u590d\u73b0\uff09\n# np.random.seed(42)\nsample_indices = np.random.choice(len(x_orig), size=3, replace=False)\n\nplt.figure(figsize=(16, 12))\nfor idx, sample_i in enumerate(sample_indices):\n    # \u83b7\u53d6\u5f53\u524d\u6837\u672c\u7684\u771f\u5b9e\u53c2\u6570\u548c\u9884\u6d4b\u53c2\u6570\n    y_true = Y_true[sample_i]  # [b0, b1, b2, a1, a2]\n    y_pred = Y_pred[sample_i]\n    b0_t, b1_t, b2_t, a1_t, a2_t = y_true\n    b0_p, b1_p, b2_p, a1_p, a2_p = y_pred\n\n    # \u8ba1\u7b97\u9891\u7387\u54cd\u5e94\uff08\u590d\u6570\u503c\uff09\n    s = 1j * w\n    H_true = (b0_t * s**2 + b1_t * s + b2_t) \/ (s**2 + a1_t * s + a2_t)\n    H_pred = (b0_p * s**2 + b1_p * s + b2_p) \/ (s**2 + a1_p * s + a2_p)\n\n    # \u8f6c\u6362\u4e3a\u5e45\u503c\uff08dB\uff09\u548c\u76f8\u4f4d\uff08\u5ea6\uff09\n    mag_true = 20 * np.log10(np.abs(H_true) + 1e-12)  # +1e-12\u907f\u514dlog(0)\n    phase_true = np.angle(H_true, deg=True)\n    mag_pred = 20 * np.log10(np.abs(H_pred) + 1e-12)\n    phase_pred = np.angle(H_pred, deg=True)\n\n    # \u5e45\u9891\u54cd\u5e94\u5b50\u56fe\uff08\u5de6\u5217\uff09\n    plt.subplot(3, 2, 2*idx + 1)\n    plt.semilogx(f\/1e3, mag_true, 'b-', linewidth=2.5, label='True System', zorder=2)\n    plt.semilogx(f\/1e3, mag_pred, 'r--', linewidth=2, label='Predicted System', zorder=3)\n    plt.title(f'Sample {sample_i}: Magnitude Response', fontsize=11, fontweight='bold')\n    plt.xlabel('Frequency (kHz)', fontsize=9)\n    plt.ylabel('Magnitude (dB)', fontsize=9)\n    plt.grid(True, which=\"both\", ls=\"--\", alpha=0.7)  # \u5bf9\u6570\u5750\u6807\u7f51\u683c\n    plt.legend(fontsize=9)\n\n    # \u76f8\u9891\u54cd\u5e94\u5b50\u56fe\uff08\u53f3\u5217\uff09\n    plt.subplot(3, 2, 2*idx + 2)\n    plt.semilogx(f\/1e3, phase_true, 'b-', linewidth=2.5, label='True System', zorder=2)\n    plt.semilogx(f\/1e3, phase_pred, 'r--', linewidth=2, label='Predicted System', zorder=3)\n    plt.title(f'Sample {sample_i}: Phase Response', fontsize=11, fontweight='bold')\n    plt.xlabel('Frequency (kHz)', fontsize=9)\n    plt.ylabel('Phase (degrees)', fontsize=9)\n    plt.grid(True, which=\"both\", ls=\"--\", alpha=0.7)\n    plt.legend(fontsize=9)\n\nplt.tight_layout()\nplt.savefig(freq_response_plot_path, dpi=300, bbox_inches='tight')\nplt.close()\nprint(f\"\u9891\u7387\u54cd\u5e94\u56fe\u5df2\u4fdd\u5b58\u5230: {freq_response_plot_path}\")\n\n# -------------------------- 8. \u6700\u7ec8\u7ed3\u679c\u8f93\u51fa --------------------------\n# \u8ba1\u7b97\u6700\u7ec8\u635f\u5931\uff08\u7528\u5168\u90e8\u539f\u59cb\u6570\u636e\uff09\nfinal_loss = model.forward(x_orig, t_orig)\nprint(f\"\\n==================== \u8bad\u7ec3\/\u8bc4\u4f30\u5b8c\u6210 ====================\")\nprint(f\"\u6700\u7ec8\u5f52\u4e00\u5316MSE\u635f\u5931: {final_loss:.6f}\")\nprint(f\"\\n\u6240\u6709\u6587\u4ef6\u4fdd\u5b58\u76ee\u5f55: {os.path.abspath(ROOT_SAVE_DIR)}\")\nprint(f\"1. \u6a21\u578b\u53c2\u6570: {os.path.basename(param_save_path)}\")\nprint(f\"2. \u635f\u5931\u6570\u636e: {os.path.basename(loss_save_path)}\")\nprint(f\"3. \u53ef\u89c6\u5316\u56fe\u7247: {os.listdir(IMAGE_SAVE_DIR)}\")\n<\/code><\/pre>\n<h2>&#8212;<\/h2>\n<h2>\u521d\u7248\u7ed3\u679c\u6f14\u793a<\/h2>\n<p>\u6309\u7167\u4e0a\u8ff0\u4ee3\u7801\u914d\u7f6e\uff0c\u4f7f\u7528cpu\u8bad\u7ec3\u4e00\u8f6e\u7ea6\u534a\u5c0f\u65f6\u3002<\/p>\n<h3>\u8bad\u7ec3\u635f\u5931\u5c55\u793a<\/h3>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/10\/loss_curve.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/10\/loss_curve.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"loss_photo\" \/><\/div><br \/>\n\u53ef\u4ee5\u53d1\u73b0\u5f53\u524d\u7f51\u7edc\u5176\u5b9e\u5f88\u65e9\u5c31\u6536\u655b\u4e86\uff0c\u6ca1\u6cd5\u8fdb\u4e00\u6b65\u7ee7\u7eed\u6536\u655b\uff0c\u6216\u8bb8\u589e\u52a0\u7f51\u7edc\u6df1\u5ea6\u6216\u8bad\u7ec3\u8f6e\u6b21\u4ecd\u53ef\u4ee5\u8fdb\u4e00\u6b65\u6539\u8fdb\u3002<\/p>\n<h3>\u53c2\u6570\u9006\u5904\u7406\u540e\u6bd4\u8f83<\/h3>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/10\/pred_vs_true.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/10\/pred_vs_true.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\u53c2\u6570\u6bd4\u8f83\" \/><\/div><br \/>\n\u53ef\u4ee5\u53d1\u73b0\u9664\u4e86\u53c2\u6570b\uff0cacde\u53c2\u6570\u90fd\u5f97\u5230\u4e86\u826f\u597d\u7684\u62df\u5408\u548c\u9884\u6d4b\uff0c\u9884\u8ba1\u5b9e\u9645\u62df\u5408\u7684\u8bef\u5dee\u4e3b\u8981\u8fd8\u662f\u53c2\u6570b\u5bfc\u81f4\u7684\uff0c\u4ecd\u53ef\u4ee5\u6539\u8fdb<\/p>\n<h3>\u968f\u673a\u771f\u5b9e\u503c\u4e0e\u9884\u6d4b\u503c\u6bd4\u8f83<\/h3>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/10\/frequency_response1.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/10\/frequency_response1.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"frequency_response1\" \/><\/div><br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/10\/frequency_response2.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/10\/frequency_response2.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"frequency_response2\" \/><\/div><br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/10\/frequency_response3.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/10\/frequency_response3.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"frequency_response3\" \/><\/div><br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/10\/frequency_response4.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/10\/frequency_response4.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"frequency_response4\" \/><\/div><\/p>\n<p>\u53ef\u4ee5\u53d1\u73b0\u5e45\u9891\u76f8\u9891\u66f2\u7ebf\u57fa\u672c\u62df\u5408\uff0c\u4f46\u4ecd\u5b58\u5728\u5fae\u5c0f\u504f\u5dee\u53ef\u4ee5\u6539\u8fdb\u4f18\u5316\u3002<\/p>\n<hr \/>\n<h2>python\u4ee3\u7801\u94fe\u63a5<\/h2>\n<p>\u901a\u8fc7\u7f51\u76d8\u5206\u4eab\u7684\u6587\u4ef6\uff1a20251013HsProject.zip<br \/>\n\u94fe\u63a5: https:\/\/pan.baidu.com\/s\/163YAoPkYVgLyKyyk-zhz5g \u63d0\u53d6\u7801: 355k<\/p>\n<h2>\u4e3b\u8981\u53c2\u8003\u4e66\u76ee\uff1a<\/h2>\n<p>\u300a\u6df1\u5ea6\u5b66\u4e60\u5165\u95e8\uff1a\u57fa\u4e8ePython\u7684\u7406\u8bba\u4e0e\u5b9e\u73b0\u300b<br \/>\n\u300a\u6df1\u5ea6\u5b66\u4e60\u8fdb\u9636\uff1a\u81ea\u7136\u8bed\u8a00\u5904\u7406\u300b<br \/>\n****\u5176\u4e2d\u4ee3\u7801\u98ce\u683c\u4e5f\u662f\u4eff\u7167\u5b83\u7684***<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u7b80\u6613\u795e\u7ecf\u7f51\u7edc\u63a8\u9884\u6d4b\u4e8c\u9636Hs\u53c2\u6570 2025.10.13 Keruone \u524d\u8a00 \u5728\u4eca\u5e74\u7535\u8d5b\u7684G\u9898\u4e2d\uff0c\u4efb\u52a1\u662f\u5b66\u4e60\u4e00\u4e2a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[13],"tags":[],"class_list":["post-480","post","type-post","status-publish","format-standard","hentry","category-iea_nbu"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/posts\/480","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/comments?post=480"}],"version-history":[{"count":1,"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/posts\/480\/revisions"}],"predecessor-version":[{"id":488,"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/posts\/480\/revisions\/488"}],"wp:attachment":[{"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/media?parent=480"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/categories?post=480"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/tags?post=480"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}