ホームページ バックエンド開発 Python チュートリアル 機械学習における C++ : Python の GIL のエスケープ

機械学習における C++ : Python の GIL のエスケープ

Sep 25, 2024 am 06:28 AM

C++ in Machine Learning : Escaping Python

導入

Python の Global Interpreter Lock (GIL) が、高い同時実行性や生のパフォーマンスを必要とする機械学習アプリケーションのボトルネックになる場合、C++ は魅力的な代替手段を提供します。このブログ投稿では、パフォーマンス、同時実行性、Python との統合に焦点を当てて、ML に C++ を活用する方法を検討します。

ブログ全文を読んでください!

GIL ボトルネックを理解する

C++ について説明する前に、GIL の影響を明確にしましょう。

  • 同時実行制限: GIL は、一度に 1 つのスレッドだけが Python バイトコードを実行することを保証します。これにより、マルチスレッド環境のパフォーマンスが大幅に制限される可能性があります。

  • 影響を受けるユースケース: リアルタイム分析、高頻度取引、または集中的なシミュレーションのアプリケーションは、多くの場合、この制限の影響を受けます。

ML に C++ を選択する理由

  • GIL なし: C++ には、真のマルチスレッドを可能にする GIL に相当するものがありません。

  • パフォーマンス: 直接メモリ管理と最適化機能により、大幅な高速化が可能です。

  • 制御: ハードウェア リソースに対するきめ細かい制御。組み込みシステムや特殊なハードウェアとインターフェイスする場合に重要です。

コード例と実装

環境のセットアップ

コーディングする前に、次のものが揃っていることを確認してください。

  • 最新の C++ コンパイラー (GCC、Clang)。
  • プロジェクト管理用の CMake (オプションですが推奨)。
  • Eigen などの線形代数演算用のライブラリ。

C++ の基本的な線形回帰

#include <vector>
#include <iostream>
#include <cmath>

class LinearRegression {
public:
    double slope = 0.0, intercept = 0.0;

    void fit(const std::vector<double>& X, const std::vector<double>& y) {
        if (X.size() != y.size()) throw std::invalid_argument("Data mismatch");

        double sum_x = 0, sum_y = 0, sum_xy = 0, sum_xx = 0;
        for (size_t i = 0; i < X.size(); ++i) {
            sum_x += X[i];
            sum_y += y[i];
            sum_xy += X[i] * y[i];
            sum_xx += X[i] * X[i];
        }

        double denom = (X.size() * sum_xx - sum_x * sum_x);
        if (denom == 0) throw std::runtime_error("Perfect multicollinearity detected");

        slope = (X.size() * sum_xy - sum_x * sum_y) / denom;
        intercept = (sum_y - slope * sum_x) / X.size();
    }

    double predict(double x) const {
        return slope * x + intercept;
    }
};

int main() {
    LinearRegression lr;
    std::vector<double> x = {1, 2, 3, 4, 5};
    std::vector<double> y = {2, 4, 5, 4, 5};

    lr.fit(x, y);

    std::cout << "Slope: " << lr.slope << ", Intercept: " << lr.intercept << std::endl;
    std::cout << "Prediction for x=6: " << lr.predict(6) << std::endl;

    return 0;
}
ログイン後にコピー

OpenMP を使用した並列トレーニング

同時実行性を示すには:

#include <omp.h>
#include <vector>

void parallelFit(const std::vector<double>& X, const std::vector<double>& y, 
                 double& slope, double& intercept) {
    #pragma omp parallel
    {
        double local_sum_x = 0, local_sum_y = 0, local_sum_xy = 0, local_sum_xx = 0;

        #pragma omp for nowait
        for (int i = 0; i < X.size(); ++i) {
            local_sum_x += X[i];
            local_sum_y += y[i];
            local_sum_xy += X[i] * y[i];
            local_sum_xx += X[i] * X[i];
        }

        #pragma omp critical
        {
            slope += local_sum_xy - (local_sum_x * local_sum_y) / X.size();
            intercept += local_sum_y - slope * local_sum_x;
        }
    }
    // Final calculation for slope and intercept would go here after the parallel region
}
ログイン後にコピー

行列演算に固有値を使用する

ロジスティック回帰などのより複雑な演算の場合:

#include <Eigen/Dense>
#include <iostream>

Eigen::VectorXd sigmoid(const Eigen::VectorXd& z) {
    return 1.0 / (1.0 + (-z.array()).exp());
}

Eigen::VectorXd logisticRegressionFit(const Eigen::MatrixXd& X, const Eigen::VectorXd& y, int iterations) {
    Eigen::VectorXd theta = Eigen::VectorXd::Zero(X.cols());

    for (int i = 0; i < iterations; ++i) {
        Eigen::VectorXd h = sigmoid(X * theta);
        Eigen::VectorXd gradient = X.transpose() * (h - y);
        theta -= gradient;
    }

    return theta;
}

int main() {
    // Example usage with dummy data
    Eigen::MatrixXd X(4, 2);
    X << 1, 1,
         1, 2,
         1, 3,
         1, 4;

    Eigen::VectorXd y(4);
    y << 0, 0, 1, 1;

    auto theta = logisticRegressionFit(X, y, 1000);
    std::cout << "Theta: " << theta.transpose() << std::endl;

    return 0;
}
ログイン後にコピー

Python との統合

Python の統合については、pybind11 の使用を検討してください:

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "your_ml_class.h"

namespace py = pybind11;

PYBIND11_MODULE(ml_module, m) {
    py::class_<YourMLClass>(m, "YourMLClass")
        .def(py::init<>())
        .def("fit", &YourMLClass::fit)
        .def("predict", &YourMLClass::predict);
}
ログイン後にコピー

これにより、次のように Python から C++ コードを呼び出すことができます。

import ml_module

model = ml_module.YourMLClass()
model.fit(X_train, y_train)
predictions = model.predict(X_test)
ログイン後にコピー

課題と解決策

  • メモリ管理: スマート ポインターまたはカスタム メモリ アロケータを使用して、メモリを効率的かつ安全に管理します。

  • エラー処理: C++ には、すぐに使えるエラー管理のための Python の例外処理がありません。堅牢な例外処理を実装します。

  • ライブラリ サポート: C++ の ML ライブラリは Python よりも少ないですが、Dlib、Shark、MLpack などのプロジェクトが強力な代替手段を提供します。

結論

C++ は、Python の GIL 制限を回避する手段を提供し、パフォーマンスが重要な ML アプリケーションにスケーラビリティを提供します。低レベルであるため、より慎重なコーディングが必要ですが、速度、制御、同時実行性の点で大きなメリットが得られます。 ML アプリケーションが限界を押し広げ続ける中、C++ は引き続き ML エンジニアのツールキットに不可欠なツールであり、特に Python と組み合わせて使いやすくした場合に顕著です。

さらなる探求

  • SIMD 操作: AVX、SSE を使用してパフォーマンスをさらに向上させる方法を検討します。
  • CUDA for C++: ML タスクの GPU アクセラレーション用。
  • 高度な ML アルゴリズム: パフォーマンスが重要なアプリケーション向けに、ニューラル ネットワークまたは SVM を C++ で実装します。

一緒に深く潜ってくれてありがとう!

機械学習における C++ の広大な可能性を一緒に探求するために時間を割いていただきありがとうございます。この旅が、Python の GIL 制限の克服について啓発しただけでなく、次の ML プロジェクトで C++ を試してみるきっかけになったことを願っています。テクノロジーで可能なことの限界を学び、押し広げることへの皆さんの献身が、イノベーションを前進させる原動力となります。実験を続け、学習を続け、そして最も重要なのは、洞察をコミュニティと共有し続けることです。次の詳細まで、コーディングを楽しんでください!

以上が機械学習における C++ : Python の GIL のエスケープの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

LinuxターミナルでPythonバージョンを表示するときに発生する権限の問題を解決する方法は? LinuxターミナルでPythonバージョンを表示するときに発生する権限の問題を解決する方法は? Apr 01, 2025 pm 05:09 PM

LinuxターミナルでPythonバージョンを表示する際の許可の問題の解決策PythonターミナルでPythonバージョンを表示しようとするとき、Pythonを入力してください...

中間の読書にどこでもfiddlerを使用するときにブラウザによって検出されないようにするにはどうすればよいですか? 中間の読書にどこでもfiddlerを使用するときにブラウザによって検出されないようにするにはどうすればよいですか? Apr 02, 2025 am 07:15 AM

fiddlereveryversings for the-middleの測定値を使用するときに検出されないようにする方法

あるデータフレームの列全体を、Python内の異なる構造を持つ別のデータフレームに効率的にコピーする方法は? あるデータフレームの列全体を、Python内の異なる構造を持つ別のデータフレームに効率的にコピーする方法は? Apr 01, 2025 pm 11:15 PM

PythonのPandasライブラリを使用する場合、異なる構造を持つ2つのデータフレーム間で列全体をコピーする方法は一般的な問題です。 2つのデータがあるとします...

プロジェクトの基本と問題駆動型の方法で10時間以内にコンピューター初心者プログラミングの基本を教える方法は? プロジェクトの基本と問題駆動型の方法で10時間以内にコンピューター初心者プログラミングの基本を教える方法は? Apr 02, 2025 am 07:18 AM

10時間以内にコンピューター初心者プログラミングの基本を教える方法は?コンピューター初心者にプログラミングの知識を教えるのに10時間しかない場合、何を教えることを選びますか...

uvicornは、serving_forever()なしでhttpリクエストをどのように継続的に聞いていますか? uvicornは、serving_forever()なしでhttpリクエストをどのように継続的に聞いていますか? Apr 01, 2025 pm 10:51 PM

UvicornはどのようにしてHTTPリクエストを継続的に聞きますか? Uvicornは、ASGIに基づく軽量のWebサーバーです。そのコア機能の1つは、HTTPリクエストを聞いて続行することです...

Investing.comの反クローラーメカニズムをバイパスするニュースデータを取得する方法は? Investing.comの反クローラーメカニズムをバイパスするニュースデータを取得する方法は? Apr 02, 2025 am 07:03 AM

Investing.comの反クラウリング戦略を理解する多くの人々は、Investing.com(https://cn.investing.com/news/latest-news)からのニュースデータをクロールしようとします。

See all articles