Tencent Music 筆記試験 0414

三重項損失の原理を紹介し、どのような種類のサンプルがあり、どのようなシナリオに使用できますか?

トリプレット損失は、ニューラル ネットワークのトレーニングに使用される損失関数です。主に、同じカテゴリのサンプル間の距離ができるだけ近くなるように、マッピング関数を学習し、サンプルを低次元空間にマッピングするために使用されます。異なるカテゴリのサンプル間は可能な限り離れています。

トリプレット損失では、各サンプルはアンカー、ポジティブ、ネガティブの 3 つのカテゴリに分類されます。このうち、Anchorはアンカーサンプルを表し、PositiveはAnchorと同じカテゴリに属する​​サンプルを表し、NegativeはAnchorと同じカテゴリに属さないサンプルを表す。

トリプレット ロスの原理は、アンカー サンプルに対して、同じカテゴリに属する​​ポジティブ サンプルと、同じカテゴリに属さないネガティブ サンプルを選択し、アンカーからポジティブまでの距離とアンカーからポジティブまでの距離を計算することです。負の場合、これら 2 つの距離間の距離が特定のしきい値よりも大きいため、モデルは、同じカテゴリのサンプルにより類似し、異なるカテゴリのサンプルとはより異なる特徴表現を学習できます。

Triplet Loss は、顔認識、画像検索、推奨システムなど、さまざまなシナリオで使用できます。これらのシナリオでは、トリプレット損失は、モデルがさまざまなカテゴリのサンプルを区別する特徴を学習するのに役立ち、それによってモデルの精度と堅牢性が向上します。

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入




T1 良好なアレイ

ここに画像の説明を挿入

最初は dp 問題と考えられていましたが、最終的には一般項を求める公式になりました。

一般的な式は次のとおりです。
ここに画像の説明を挿入

T1: 数学的再帰後の式は fn=(n-1)*2^(n+1) であり、高速なパワーで計算できます。


これは高速なパワーで解決できますが、型がlonglongであることに注意してください。

#define MOD 1000000007
typedef long long ll;

class Solution {
    
    
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param n int整型
     * @return int整型
     */
    ll fastpow(ll n, ll val){
    
    
        if(n == 1) return val;
        if(n == 0) return 1;

        ll x = fastpow(n/2, val);
        return n % 2 ? ((x*x) % MOD*val) % MOD : (x*x) % MOD;
    }

    int fun(int n) {
    
    
        return (ll)((n-1)*fastpow(n+1, 2)) % MOD;
    }
};

ここに画像の説明を挿入

ここに画像の説明を挿入


最初の質問では高速パワーを使用できないのはなぜですか?
長い長い問題になるはずです。int が定義されている場合は機能しません。最初のテスト サンプルはうんざりです。

最初の問題の公式から抜け出すにはどうすればよいでしょうか?
手遊び、等比数列の合計、高校の数学の問題のような感じです

ここに画像の説明を挿入




T2バイナリツリー

ここに画像の説明を挿入

Xiaohong はフォーク ツリーを取得し、各ノードの値をサブツリー ノードの積の末尾にあるゼロの数として定義しました。

次に、フォーク ツリーを返します。ツリーの構造は指定されたバイナリ ツリーと同じです。各ノードの重みをノードの値に置き換えます。

  • 二分木のノードの数は1 0 5 10^5を超えません。1 05
  • 二分木の各ノードの重みは1 0 9 10^9以下です。1 0正の整数9

ここに画像の説明を挿入

T2:
単純な DFS

タイトルの意味は、

  • 各ノードのサブツリー内のすべての要素の積で 0 の数を見つけます (10->1 100->2 500->2)
    DFS は、各要素 %2 の数 a と、自分自身の下の %5 の数 b をカウントします。 -orientation
    和積内の 0 の数を求め、min(a,b) に変換します。

ここに画像の説明を挿入

class Solution {
    
    
public:
   TreeNode* valueOfTree(TreeNode* root) {
    
    
       // write code here
       dfs(root);
       return root;
   }

   pair<int,int> dfs(TreeNode* node){
    
    
       if(node == nullptr){
    
    
           return {
    
    0, 0};
       }
       auto l = dfs(node->left);
       auto r = dfs(node->right);
       auto cur = cal(node->val);
       auto n2 = cur.first + l.first + r.first;
       auto n5 = cur.second + l.second + r.second;
       node->val = min(n2, n5);
       return {
    
    n2, n5};
   }

   //末尾0的数量与因子2和5的数量有关系
   pair<int,int> cal(int num){
    
    
       int n2 = 0, n5 = 0;
       while(num%2 == 0){
    
    
           num /= 2;
           n2 += 1;
       }
       while(num%5 == 0){
    
    
           num /= 5;
           n5 += 1;
       }
       return {
    
    n2,n5};
   }
};

ここに画像の説明を挿入
ここに画像の説明を挿入




T3 はサイズ n*(n+1)/2 の配列を構築します


Xiaohong は、正の整数 n が与えられた場合、 1 1、2 2、... n n でサイズが n*(n+ 1)/2 の配列を構築し、隣接する 2 つの要素が等しくないことを要求します。彼女を助けてもらえますか

答えは一意ではなく、
複数の解がある場合には任意の法的解を出力することができます。
データ範囲: 1 < n< 500

例1

  • 入力
    3
  • 出力
    [3,2,3,2,3,1]

ここに画像の説明を挿入

T3: 貪欲

最も残っている数値を最初に保存します (ヒープの最上位要素が現在の要素と同じでない場合は、大きなルート ヒープを使用して各数値の残り回数を記録します)

  • 次に、ヒープの先頭にある要素の数 -1 を直接プッシュします。

同じ場合は、要素をプッシュ ヒープの先頭にポップします

  • 以前にポップした要素をプッシュするだけです)

3 番目の質問は非常に簡単で、321 32、4321 432 43 だけです。欲張らないでください。2 行のコードで解決します

  • for ループは 2 つだけ

ここに画像の説明を挿入

class Solution {
    
    
public:
   vector<int> fun(int n) {
    
    
       // write code here
       int len = n*(n+1) / 2;
       vector<int> ans(len, 0);
       ans[0] = n;

       int start = 1;
       int j = 1;
       for(int i=1; i<len; i++){
    
    
           ans[i] = j++;
           if(j > n){
    
    
               start += 1;
               j = start;
           }
       }

       return ans;
   }
};

def construct_array(n):
    arr = [0] * (n * (n + 1) // 2)
    index = 0
    for i in range(1, n+1):
        count = i
        while count > 0:
            arr[index] = i
            index += 2*i if count == i else 1
            count -= 1
    return arr

関数construct_array(n)は、要件を満たす長さn*(n+1)/2の配列を返します。このアルゴリズムの考え方は、各数値 i について、それを配列内で i 回繰り返しますが、i 位置ごとに位置をスキップすることで、隣接する要素が等しくないことを保証できるというものです。

たとえば、n=3 の場合、構築される配列は [1,2,1,3,2,3] になります。このアルゴリズムでは、まず長さ n*(n+1)/2 の配列を初期化し、次に 1 から n までの各数値 i を列挙します。各数値 i について、それを i 回繰り返し、上記のルールに従って配列に入れます。具体的には、数値 i を挿入する現在の位置を示すポインター インデックスを維持する必要があります。次に、i から開始して、i を配列のインデックス位置に挿入します。次に、挿入する i がまだ残っている場合は、インデックスを 2*i 位置だけスキップします。これにより、隣接する要素が等しくないことが保証されます。挿入する i が 1 つだけ残っている場合は、インデックスを 1 位置スキップします。

最後に、構築された配列を返すだけです。


ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_43338969/article/details/130156144